Groups | Blog | Home
all groups > sql server programming > may 2004 >

sql server programming : IndexScan+Filter =(implies)=> Better Index Possible?


Ian Boyd
5/26/2004 11:24:36 PM
Part of one of my queries performs
an index scan (generates 1.8M rows), and then
filters that set (down to 61 rows).

The plan text follows.

My question is (because i just don't know) shouldn't an IndexScan followed
by a Filter
operation be able to be converted into an index seek? Or at least not have
it generate
so many candidate rows in the inital scan?

Why not apply the Filter when doing the scan in the first place? You (you
being
the SQL Server engine) would save yourself a lot of work).

You'll notice the Filter operation is performing some calculations on dates,
but if i had a convering index order first by the dates, shouldn't that be
able to be taken care of in the initial scan?

Formatted query plan output of the two offending stages:

Index Scan:
OBJECT: Reservations.IX_Reservations_ConflictsCheckingHelper
WHERE:( Reservations.ReservationGUID <> Reservations.ReservationGUID
AND Reservations.Status <> 'rsCancelled')
AND Reservations.Status <> 'rsNoShow'

RowCount: 1,888,409

Filter
WHERE:
( (Reservations.ArrivalBayGUID=Reservations.ArrivalBayGUID
AND Reservations.ScheduledArrivalDate >= Reservations.ScheduledArrivalDate)
AND Reservations.ScheduledArrivalDate <= dateadd(minute, 15,
Reservations.ScheduledArrivalDate)
)
OR
( (Reservations.DepartureBayGUID=Reservations.ArrivalBayGUID
AND Reservations.ScheduledDepartureDate >=
Reservations.ScheduledArrivalDate)
AND Reservations.ScheduledDepartureDate <= dateadd(minute, 15,
[Reservations].[ScheduledArrivalDate]))
)
OR
( ([Reservations].[ArrivalBayGUID]=[Reservations].[DepartureBayGUID]
AND
[Reservations].[ScheduledArrivalDate]>=[Reservations].[ScheduledDepartureDat
e])
AND [Reservations].[ScheduledArrivalDate]<=dateadd(minute, 15,
[Reservations].[ScheduledDepartureDate]))
)
OR
( ([Reservations].[DepartureBayGUID]=[Reservations].[DepartureBayGUID]
AND
[Reservations].[ScheduledDepartureDate]>=[Reservations].[ScheduledDepartureD
ate])
AND [Reservations].[ScheduledDepartureDate]<=dateadd(minute, 15,
[Reservations].[ScheduledDepartureDate]
)

RowCount: 61

Ian Boyd
5/27/2004 8:22:03 AM
Now i'm kinda confused. The query itself runs faster, and it has a lower
subtree cost (18,000 vs 24)

Table 'Worktable'. Scan count 52, logical reads 58229, physical reads 0,
read-ahead reads 0.
Table 'Reservations'. Scan count 7, logical reads 1717, physical reads 1,
read-ahead reads 78.
Table 'Worktable'. Scan count 56, logical reads 58239, physical reads 0,
read-ahead reads 0.
Table 'Worktable'. Scan count 59, logical reads 48039, physical reads 0,
read-ahead reads 0.
Table 'Worktable'. Scan count 100, logical reads 48121, physical reads 0,
read-ahead reads 0.

But it has a lot more logical reads (i used DBCC DropCleanBuffers before
running query).

(Without drop clean buffers:
Table 'Worktable'. Scan count 52, logical reads 58229, physical reads 0,
read-ahead reads 0.
Table 'Reservations'. Scan count 7, logical reads 1717, physical reads 0,
read-ahead reads 0.
Table 'Worktable'. Scan count 56, logical reads 58239, physical reads 0,
read-ahead reads 0.
Table 'Worktable'. Scan count 59, logical reads 48039, physical reads 0,
read-ahead reads 0.
Table 'Worktable'. Scan count 100, logical reads 48121, physical reads 0,
read-ahead reads 0.
)

So is this really better?


Also, the server wasn't able to perform that conversion on it's own?
Can you explain logically how this is better?

With the OR clauses, i thought it would perform "short-circuit evaluation".
As soon as it finds an or clause that fits the criteria, it can bail out.
Verses having to run all union all conditions?



[quoted text, click to view]

Uri Dimant
5/27/2004 8:34:36 AM
Ian
I suggest you to re-write all 'OR' conditions in the WHERE clause to UNION .
It may cause to query optomizer to use INDEX SEEK.
Also you have to create an appropriate indexes on the table.

For example
SELECT col FROM Table WHERE col1=1 OR col2=2
try to use
SELECT col FROM Table WHERE col1=1
UNION -----ALL
SELECT col FROM Table WHERE col2=2

[quoted text, click to view]

Hugo Kornelis
5/27/2004 3:33:48 PM
[quoted text, click to view]

(snip)
[quoted text, click to view]

Let's assume you have two phone books for New York. One sorted by name,
the other one sorted by address (not commercially available). Now, if You
had to find everybody named White *or* living on 42nd Avenue, would you
browse one book from beginning to end, or would you rather first get the
Whites from one book, then get the people living 42nd Avenue from the
second book, then take some time to remove duplicates?

(snip)

Best, Hugo
--

AddThis Social Bookmark Button