Home All Groups Group Topic Archive Search About

any performance diff using -Between- or >= and <= ?

Author
28 Jul 2006 7:21 PM
Rich
Hello,

I need to run several queries that use 3 date args.  Is there any
significant different between the following select statements?  Performance? 
what you capture?

Select ....
Where (date1 between @a and @b) and (date2 between @c and @d)
and (date3 between @e and @f)

Or

Select ....
Where (date1>= @a and date1<=@b) and (date2>=@c and date2<=@d)
and (date3>=@e and date2<=@f)

The source data table contains between 35000 - 40000 rows and 35 columns.

Thanks,
Rich

Author
28 Jul 2006 7:38 PM
Andrew J. Kelly
A BETWEEN is essentially the same thing as a >= and <= and AFAIK the
optimizer will treat them the same way.

--
Andrew J. Kelly SQL MVP

Show quote
"Rich" <R***@discussions.microsoft.com> wrote in message
news:5810E81B-06A5-44DD-8442-B2C37A0D50F3@microsoft.com...
> Hello,
>
> I need to run several queries that use 3 date args.  Is there any
> significant different between the following select statements?
> Performance?
> what you capture?
>
> Select ....
> Where (date1 between @a and @b) and (date2 between @c and @d)
> and (date3 between @e and @f)
>
> Or
>
> Select ....
> Where (date1>= @a and date1<=@b) and (date2>=@c and date2<=@d)
> and (date3>=@e and date2<=@f)
>
> The source data table contains between 35000 - 40000 rows and 35 columns.
>
> Thanks,
> Rich
Author
28 Jul 2006 7:49 PM
Tibor Karaszi
I believe you still see this in the execution plan, i.e., the BETWEEN is converted to >= and <=.

Show quote
"Andrew J. Kelly" <sqlmvpnooospam@shadhawk.com> wrote in message
news:ODjgd1nsGHA.4608@TK2MSFTNGP04.phx.gbl...
>A BETWEEN is essentially the same thing as a >= and <= and AFAIK the optimizer will treat them the
>same way.
>
> --
> Andrew J. Kelly SQL MVP
>
> "Rich" <R***@discussions.microsoft.com> wrote in message
> news:5810E81B-06A5-44DD-8442-B2C37A0D50F3@microsoft.com...
>> Hello,
>>
>> I need to run several queries that use 3 date args.  Is there any
>> significant different between the following select statements? Performance?
>> what you capture?
>>
>> Select ....
>> Where (date1 between @a and @b) and (date2 between @c and @d)
>> and (date3 between @e and @f)
>>
>> Or
>>
>> Select ....
>> Where (date1>= @a and date1<=@b) and (date2>=@c and date2<=@d)
>> and (date3>=@e and date2<=@f)
>>
>> The source data table contains between 35000 - 40000 rows and 35 columns.
>>
>> Thanks,
>> Rich
>
>
Author
28 Jul 2006 7:54 PM
David Portas
Show quote
"Rich" <R***@discussions.microsoft.com> wrote in message
news:5810E81B-06A5-44DD-8442-B2C37A0D50F3@microsoft.com...
> Hello,
>
> I need to run several queries that use 3 date args.  Is there any
> significant different between the following select statements?
> Performance?
> what you capture?
>
> Select ....
> Where (date1 between @a and @b) and (date2 between @c and @d)
> and (date3 between @e and @f)
>
> Or
>
> Select ....
> Where (date1>= @a and date1<=@b) and (date2>=@c and date2<=@d)
> and (date3>=@e and date2<=@f)
>
> The source data table contains between 35000 - 40000 rows and 35 columns.
>
> Thanks,
> Rich

No difference.

BETWEEN is not always convenient to use with datetimes. Especially not if
you need to compare whole days but the datetimes may have times other than
midnight. Usually >= and < makes more sense.

For example, this:

dt >= '20060101' AND dt < '20070101'

should be easier to type and understand than the equivalent expression using
BETWEEN:

dt BETWEEN '20060101' AND '2006-12-31T23:59:59.997'

--
David Portas, SQL Server MVP

Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.

SQL Server Books Online:
http://msdn2.microsoft.com/library/ms130214(en-US,SQL.90).aspx
--
Author
28 Jul 2006 8:04 PM
Arnie Rowland
Interestingly enough, I find that there is actually a speed/efficiency difference. As of yet, I don't truly understand the details -it seems as though they should both use indexes the same -but obviously not.

Based on the following test, I accept that BETWEEN will operate faster that the equivalent [ >= AND < ]. While the difference is small, it is measurable.

This test uses a very small table containing 100k rows.

--
Arnie Rowland, Ph.D.
Westwood Consulting, Inc

Most good judgment comes from experience.
Most experience comes from bad judgment.
- Anonymous


/*
   Demonstration of Query speed effect from
   Using BETWEEN vs. [ >= AND < ]

   Kudos to the many who inspire.

*/

CREATE TABLE #Test
  (    ID       int primary key
     , TestDate datetime
   )

CREATE INDEX dt_index ON #Test ( TestDate )

DECLARE
     @iCounter  int
   , @Start1    datetime
   , @Stop1     datetime
   , @Start2    datetime
   , @Stop2     datetime
   , @Start3    datetime
   , @Stop3     datetime

SET @iCounter = 0

SET NOCOUNT ON

SET @Start1 = getdate()

WHILE @iCounter < 100000

   BEGIN

      INSERT INTO #Test ( ID, TestDate )
         VALUES ( @iCounter, convert( datetime, '01/01/2000') + ( @iCounter / 4 ))

      SET @iCounter = ( @iCounter + 1 )

   END

SET @Stop1 = getdate()

SET @Start2 = getdate()

   SELECT *
   FROM #Test
   WHERE TestDate BETWEEN '04/01/2000' AND '03/31/2001'

SET @Stop2 = getdate()

SET @Start3 = getdate()

   SELECT *
   FROM #Test
   WHERE TestDate >= '04/01/2000' AND TestDate < '04/01/2001'

SET @Stop3 = getdate()

DROP TABLE #Test

PRINT ( 'Loading Data...' )
PRINT ( 'Start at: ' + cast( @Start1 AS varchar(30) ))
PRINT ( ' Stop at: ' + cast( @Stop1 AS varchar(30) ))
PRINT ( 'Time to Load Data: ' + cast( datediff( ms, @Start1, @Stop1 ) AS varchar(10) ))
PRINT ( '' )
PRINT ( 'BETWEEN Test' )
PRINT ( 'Start at: ' + cast( @Start2 AS varchar(30) ))
PRINT ( ' Stop at: ' + cast( @Stop2 AS varchar(30) ))
PRINT ( 'Time Difference: ' + cast( datediff( ms, @Start2, @Stop2 ) AS varchar(10) ))
PRINT ( '' )
PRINT ( '>< Test ' )
PRINT ( 'Start at: ' + cast( @Start3 AS varchar(30) ))
PRINT ( ' Stop at: ' + cast( @Stop3 AS varchar(30) ))
PRINT ( 'Time Difference: ' + cast( datediff( ms, @Start3, @Stop3 ) AS varchar(10) ))


Show quote
"Rich" <R***@discussions.microsoft.com> wrote in message news:5810E81B-06A5-44DD-8442-B2C37A0D50F3@microsoft.com...
> Hello,
>
> I need to run several queries that use 3 date args.  Is there any
> significant different between the following select statements?  Performance? 
> what you capture?
>
> Select ....
> Where (date1 between @a and @b) and (date2 between @c and @d)
> and (date3 between @e and @f)
>
> Or
>
> Select ....
> Where (date1>= @a and date1<=@b) and (date2>=@c and date2<=@d)
> and (date3>=@e and date2<=@f)
>
> The source data table contains between 35000 - 40000 rows and 35 columns.
>
> Thanks,
> Rich
Author
28 Jul 2006 9:26 PM
Steve Kass
Arnie,

I don't think your test measures anything to do with BETWEEN vs. </>. 
Virtually all of the time spent by your queries is to present the output
to the user, so you are measuring the difference between printing a
bunch of output when the output window is empty vs. printing a bunch of
output when the output window is full.

Try timing your two queries in the opposite order.  You may find, like I
did, that the second query is reproducibly the slower one.

Steve Kass
Drew University
www.stevekass.com

Arnie Rowland wrote:

Show quote
>Interestingly enough, I find that there is actually a speed/efficiency difference. As of yet, I don't truly understand the details -it seems as though they should both use indexes the same -but obviously not.
>
>Based on the following test, I accept that BETWEEN will operate faster that the equivalent [ >= AND < ]. While the difference is small, it is measurable.
>
>This test uses a very small table containing 100k rows.
>

>
Author
28 Jul 2006 11:47 PM
Alexander Kuznetsov
Arnie Rowland wrote:
Show quote
>
> SET @Start2 = getdate()
>
>    SELECT *
>    FROM #Test
>    WHERE TestDate BETWEEN '04/01/2000' AND '03/31/2001'
>
> SET @Stop2 = getdate()
>
> SET @Start3 = getdate()
>
>    SELECT *
>    FROM #Test
>    WHERE TestDate >= '04/01/2000' AND TestDate < '04/01/2001'
>
> SET @Stop3 = getdate()

Arnie,

1. I would suggest a much bigger dataset.

2.   Yur statement

SELECT *
    FROM #Test

will spend some time
2.1 accessing the data and
2.2 some time constructing and delivering the resultset

I would eliminate 2.2 altogether - if you have any differences in 2.1,
they will be more prononunced. Try this:

SELECT @c = count(*)
    FROM #Test
    WHERE TestDate >= '04/01/2000' AND TestDate < '04/01/2001'
-------------- possibly any non-indexable and simple criteria here
-- such as modulo of some numeric column = 1 an d modulo of some other
numeric column = 2

Good luck!
Author
29 Jul 2006 1:09 AM
Arnie Rowland
Good Ideas. I'll test completely removing the production of a resultset and
radically increase the dataset.

--
Arnie Rowland, Ph.D.
Westwood Consulting, Inc

Most good judgment comes from experience.
Most experience comes from bad judgment.
- Anonymous


Show quote
"Alexander Kuznetsov" <AK_TIREDOFSPAM@hotmail.COM> wrote in message
news:1154130455.887848.268470@m79g2000cwm.googlegroups.com...
> Arnie Rowland wrote:
>>
>> SET @Start2 = getdate()
>>
>>    SELECT *
>>    FROM #Test
>>    WHERE TestDate BETWEEN '04/01/2000' AND '03/31/2001'
>>
>> SET @Stop2 = getdate()
>>
>> SET @Start3 = getdate()
>>
>>    SELECT *
>>    FROM #Test
>>    WHERE TestDate >= '04/01/2000' AND TestDate < '04/01/2001'
>>
>> SET @Stop3 = getdate()
>
> Arnie,
>
> 1. I would suggest a much bigger dataset.
>
> 2.   Yur statement
>
> SELECT *
>    FROM #Test
>
> will spend some time
> 2.1 accessing the data and
> 2.2 some time constructing and delivering the resultset
>
> I would eliminate 2.2 altogether - if you have any differences in 2.1,
> they will be more prononunced. Try this:
>
> SELECT @c = count(*)
>    FROM #Test
>    WHERE TestDate >= '04/01/2000' AND TestDate < '04/01/2001'
> -------------- possibly any non-indexable and simple criteria here
> -- such as modulo of some numeric column = 1 an d modulo of some other
> numeric column = 2
>
> Good luck!
>
Author
29 Jul 2006 12:10 AM
Andrew J. Kelly
BETWEEN is not the same as >= and <.  It is equal to >= AND <=. They are different and can return different results depending on what your data looks like. The optimizer may even choose a different plan again depending on the data.

--
Andrew J. Kelly SQL MVP

  "Arnie Rowland" <arnie at 1568 . moc> wrote in message news:eKHsZEosGHA.372@TK2MSFTNGP06.phx.gbl...
  Interestingly enough, I find that there is actually a speed/efficiency difference. As of yet, I don't truly understand the details -it seems as though they should both use indexes the same -but obviously not.

  Based on the following test, I accept that BETWEEN will operate faster that the equivalent [ >= AND < ]. While the difference is small, it is measurable.

  This test uses a very small table containing 100k rows.

  --
  Arnie Rowland, Ph.D.
  Westwood Consulting, Inc

  Most good judgment comes from experience.
  Most experience comes from bad judgment.
  - Anonymous


  /*
     Demonstration of Query speed effect from
     Using BETWEEN vs. [ >= AND < ]

     Kudos to the many who inspire.

  */

  CREATE TABLE #Test
    (    ID       int primary key
       , TestDate datetime
     )

  CREATE INDEX dt_index ON #Test ( TestDate )

  DECLARE
       @iCounter  int
     , @Start1    datetime
     , @Stop1     datetime
     , @Start2    datetime
     , @Stop2     datetime
     , @Start3    datetime
     , @Stop3     datetime

  SET @iCounter = 0

  SET NOCOUNT ON

  SET @Start1 = getdate()

  WHILE @iCounter < 100000

     BEGIN

        INSERT INTO #Test ( ID, TestDate )
           VALUES ( @iCounter, convert( datetime, '01/01/2000') + ( @iCounter / 4 ))

        SET @iCounter = ( @iCounter + 1 )

     END

  SET @Stop1 = getdate()

  SET @Start2 = getdate()

     SELECT *
     FROM #Test
     WHERE TestDate BETWEEN '04/01/2000' AND '03/31/2001'

  SET @Stop2 = getdate()

  SET @Start3 = getdate()

     SELECT *
     FROM #Test
     WHERE TestDate >= '04/01/2000' AND TestDate < '04/01/2001'

  SET @Stop3 = getdate()

  DROP TABLE #Test

  PRINT ( 'Loading Data...' )
  PRINT ( 'Start at: ' + cast( @Start1 AS varchar(30) ))
  PRINT ( ' Stop at: ' + cast( @Stop1 AS varchar(30) ))
  PRINT ( 'Time to Load Data: ' + cast( datediff( ms, @Start1, @Stop1 ) AS varchar(10) ))
  PRINT ( '' )
  PRINT ( 'BETWEEN Test' )
  PRINT ( 'Start at: ' + cast( @Start2 AS varchar(30) ))
  PRINT ( ' Stop at: ' + cast( @Stop2 AS varchar(30) ))
  PRINT ( 'Time Difference: ' + cast( datediff( ms, @Start2, @Stop2 ) AS varchar(10) ))
  PRINT ( '' )
  PRINT ( '>< Test ' )
  PRINT ( 'Start at: ' + cast( @Start3 AS varchar(30) ))
  PRINT ( ' Stop at: ' + cast( @Stop3 AS varchar(30) ))
  PRINT ( 'Time Difference: ' + cast( datediff( ms, @Start3, @Stop3 ) AS varchar(10) ))


Show quote
  "Rich" <R***@discussions.microsoft.com> wrote in message news:5810E81B-06A5-44DD-8442-B2C37A0D50F3@microsoft.com...
  > Hello,
  >
  > I need to run several queries that use 3 date args.  Is there any
  > significant different between the following select statements?  Performance? 
  > what you capture?
  >
  > Select ....
  > Where (date1 between @a and @b) and (date2 between @c and @d)
  > and (date3 between @e and @f)
  >
  > Or
  >
  > Select ....
  > Where (date1>= @a and date1<=@b) and (date2>=@c and date2<=@d)
  > and (date3>=@e and date2<=@f)
  >
  > The source data table contains between 35000 - 40000 rows and 35 columns.
  >
  > Thanks,
  > Rich
Author
29 Jul 2006 1:06 AM
Arnie Rowland
Thanks for the comments -they help.

I was concerned about the issues that Steve related to output to display buffer. I had also tested in reverse order with no discernable change in the timing differences. I've even tested by using INSERT INTO instead of just a SELECT. While there is a substantial hit for the display output buffer, INSERT INTO a table variable or #Temp table still shows a measurable difference between the two.

I've now added proc buffer and cache purging. I'm trying to remove as much testing bias as possible.

AS Erland indicated, the difference shouldn't rate significance. And, if the two methods were interchangeable, the time difference would be just 'noise' -yet as the row count goes up in the table, it doesn't seem to drop to a level of insignificance -and I can't dismiss it as just 'noise'.

So far, all of the various permutations I've tried still show a very small, but measurable advantage to [BETWEEN].

I will soon post some additional results as I have them, and, who know, perhaps even a retraction from my original assertion.

--
Arnie Rowland, Ph.D.
Westwood Consulting, Inc

Most good judgment comes from experience.
Most experience comes from bad judgment.
- Anonymous


  "Arnie Rowland" <arnie at 1568 . moc> wrote in message news:eKHsZEosGHA.372@TK2MSFTNGP06.phx.gbl...
  Interestingly enough, I find that there is actually a speed/efficiency difference. As of yet, I don't truly understand the details -it seems as though they should both use indexes the same -but obviously not.

  Based on the following test, I accept that BETWEEN will operate faster that the equivalent [ >= AND < ]. While the difference is small, it is measurable.

  This test uses a very small table containing 100k rows.

  --
  Arnie Rowland, Ph.D.
  Westwood Consulting, Inc

  Most good judgment comes from experience.
  Most experience comes from bad judgment.
  - Anonymous


  /*
     Demonstration of Query speed effect from
     Using BETWEEN vs. [ >= AND < ]

     Kudos to the many who inspire.

  */

  CREATE TABLE #Test
    (    ID       int primary key
       , TestDate datetime
     )

  CREATE INDEX dt_index ON #Test ( TestDate )

  DECLARE
       @iCounter  int
     , @Start1    datetime
     , @Stop1     datetime
     , @Start2    datetime
     , @Stop2     datetime
     , @Start3    datetime
     , @Stop3     datetime

  SET @iCounter = 0

  SET NOCOUNT ON

  SET @Start1 = getdate()

  WHILE @iCounter < 100000

     BEGIN

        INSERT INTO #Test ( ID, TestDate )
           VALUES ( @iCounter, convert( datetime, '01/01/2000') + ( @iCounter / 4 ))

        SET @iCounter = ( @iCounter + 1 )

     END

  SET @Stop1 = getdate()

  SET @Start2 = getdate()

     SELECT *
     FROM #Test
     WHERE TestDate BETWEEN '04/01/2000' AND '03/31/2001'

  SET @Stop2 = getdate()

  SET @Start3 = getdate()

     SELECT *
     FROM #Test
     WHERE TestDate >= '04/01/2000' AND TestDate < '04/01/2001'

  SET @Stop3 = getdate()

  DROP TABLE #Test

  PRINT ( 'Loading Data...' )
  PRINT ( 'Start at: ' + cast( @Start1 AS varchar(30) ))
  PRINT ( ' Stop at: ' + cast( @Stop1 AS varchar(30) ))
  PRINT ( 'Time to Load Data: ' + cast( datediff( ms, @Start1, @Stop1 ) AS varchar(10) ))
  PRINT ( '' )
  PRINT ( 'BETWEEN Test' )
  PRINT ( 'Start at: ' + cast( @Start2 AS varchar(30) ))
  PRINT ( ' Stop at: ' + cast( @Stop2 AS varchar(30) ))
  PRINT ( 'Time Difference: ' + cast( datediff( ms, @Start2, @Stop2 ) AS varchar(10) ))
  PRINT ( '' )
  PRINT ( '>< Test ' )
  PRINT ( 'Start at: ' + cast( @Start3 AS varchar(30) ))
  PRINT ( ' Stop at: ' + cast( @Stop3 AS varchar(30) ))
  PRINT ( 'Time Difference: ' + cast( datediff( ms, @Start3, @Stop3 ) AS varchar(10) ))


Show quote
  "Rich" <R***@discussions.microsoft.com> wrote in message news:5810E81B-06A5-44DD-8442-B2C37A0D50F3@microsoft.com...
  > Hello,
  >
  > I need to run several queries that use 3 date args.  Is there any
  > significant different between the following select statements?  Performance? 
  > what you capture?
  >
  > Select ....
  > Where (date1 between @a and @b) and (date2 between @c and @d)
  > and (date3 between @e and @f)
  >
  > Or
  >
  > Select ....
  > Where (date1>= @a and date1<=@b) and (date2>=@c and date2<=@d)
  > and (date3>=@e and date2<=@f)
  >
  > The source data table contains between 35000 - 40000 rows and 35 columns.
  >
  > Thanks,
  > Rich
Author
28 Jul 2006 8:43 PM
Rich
Thank you all for your replies.  And thanks Arnie(dr) for the sample test. 
Here are the results from my workstation:

Loading Data...
Start at: Jul 28 2006  1:39PM
Stop at: Jul 28 2006  1:39PM
Time to Load Data: 3906

BETWEEN Test
Start at: Jul 28 2006  1:39PM
Stop at: Jul 28 2006  1:39PM
Time Difference: 0

>< Test
Start at: Jul 28 2006  1:39PM
Stop at: Jul 28 2006  1:39PM
Time Difference: 16





Show quote
"Rich" wrote:

> Hello,
>
> I need to run several queries that use 3 date args.  Is there any
> significant different between the following select statements?  Performance? 
> what you capture?
>
> Select ....
> Where (date1 between @a and @b) and (date2 between @c and @d)
> and (date3 between @e and @f)
>
> Or
>
> Select ....
> Where (date1>= @a and date1<=@b) and (date2>=@c and date2<=@d)
> and (date3>=@e and date2<=@f)
>
> The source data table contains between 35000 - 40000 rows and 35 columns.
>
> Thanks,
> Rich
Author
28 Jul 2006 9:05 PM
Arnie Rowland
And don't forget the importance of David's comments about handling dates
with BETWEEN.

--
Arnie Rowland, Ph.D.
Westwood Consulting, Inc

Most good judgment comes from experience.
Most experience comes from bad judgment.
- Anonymous


Show quote
"Rich" <R***@discussions.microsoft.com> wrote in message
news:F21202B2-65FF-4A38-9B64-61A49C9BAD9D@microsoft.com...
> Thank you all for your replies.  And thanks Arnie(dr) for the sample test.
> Here are the results from my workstation:
>
> Loading Data...
> Start at: Jul 28 2006  1:39PM
> Stop at: Jul 28 2006  1:39PM
> Time to Load Data: 3906
>
> BETWEEN Test
> Start at: Jul 28 2006  1:39PM
> Stop at: Jul 28 2006  1:39PM
> Time Difference: 0
>
>>< Test
> Start at: Jul 28 2006  1:39PM
> Stop at: Jul 28 2006  1:39PM
> Time Difference: 16
>
>
>
>
>
> "Rich" wrote:
>
>> Hello,
>>
>> I need to run several queries that use 3 date args.  Is there any
>> significant different between the following select statements?
>> Performance?
>> what you capture?
>>
>> Select ....
>> Where (date1 between @a and @b) and (date2 between @c and @d)
>> and (date3 between @e and @f)
>>
>> Or
>>
>> Select ....
>> Where (date1>= @a and date1<=@b) and (date2>=@c and date2<=@d)
>> and (date3>=@e and date2<=@f)
>>
>> The source data table contains between 35000 - 40000 rows and 35 columns.
>>
>> Thanks,
>> Rich
Author
28 Jul 2006 9:59 PM
Erland Sommarskog
Rich (R***@discussions.microsoft.com) writes:
Show quote
> Thank you all for your replies.  And thanks Arnie(dr) for the sample test. 
> Here are the results from my workstation:
>
> Loading Data...
> Start at: Jul 28 2006  1:39PM
>  Stop at: Jul 28 2006  1:39PM
> Time to Load Data: 3906

> BETWEEN Test
> Start at: Jul 28 2006  1:39PM
>  Stop at: Jul 28 2006  1:39PM
> Time Difference: 0

>>< Test
> Start at: Jul 28 2006  1:39PM
>  Stop at: Jul 28 2006  1:39PM
> Time Difference: 16


And a difference of 16 is not significant. I usually find when timing
queries that I rarely data between 0 and 16. I may occassionally see 13,
but that's that. As a rule of thumb, I regard anything below 50 as too
inaccurate to be significant.


--
Erland Sommarskog, SQL Server MVP, esq***@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

AddThis Social Bookmark Button