use t1create database t1use t1drop table t1create table t1(col1 int, col2 nchar(2000), col3 time)create index i1 on t1(col1) where col1 > 5 and col1 < 20create index i1 on t1(col1) where col1 > 5 and col1 < 20declare @p int set @p =0while @p < 20000begininsert into t1(col1) values (rand()*10000)set @p=@p+1endcreate index i2 on t1(col1) where col1 > 25 and col1 < 40OK I added a second index over a different range in the same column. This is not a case that the SQL Server 2005 optimizer had to handle.query 1: a query with a disjunction (OR) of ranges (BETWEEN/AND).select col1 from t1 where (col1 > 5 and col1 < 20) or (col1 > 25 and col1 < 40) |--Table Scan(OBJECT:([t1].[dbo].[t1]), WHERE:([t1].[dbo].[t1].[col1]>(5) AND [t1].[dbo].[t1].[col1]<(20) OR [t1].[dbo].[t1].[col1]>(25) AND [t1].[dbo].[t1].[col1]<(40)))Hrm. Well, there doesn't seem to be code in CTP that does index unions for cases like this, unfortunately.Hinting isn't an option either because the index hint code returns an error if the hinted index does notcompletely cover the index. On my machine, I get:(43 row(s) affected) SQL Server Execution Times: CPU time = 47 ms, elapsed time = 2661 ms.That elapsed time is mostly reading pages off my IDE drive. To be clear, this is the _cold cache_ time, which means that I ran "DBCC dropcleanbuffers" before my run. This throws out all of the buffer pool pages and forces a read from disk. One assumption in the costing model for the SQL Server QP is that thepages are _not_ in memory already (and there are cases where this becomes interesting). For this example,it just means that we have a big table scan with lots of IOs to do (and is therefore slow).Second example: IN listsselect col1 from t1 where col1 in (6, 7, 8, 26) |--Table Scan(OBJECT:([t1].[dbo].[t1]), WHERE:([t1].[dbo].[t1].[col1]=(6) OR [t1].[dbo].[t1].[col1]=(7) OR [t1].[dbo].[t1].[col1]=(8) OR [t1].[dbo].[t1].[col1]=(26)))
select col1 from t1 where (col1 > 5 and col1 < 20) or (col1 > 25 and col1 < 40)
select col1 from t1 where col1 in (6, 7, 8, 26)
select col1 from t1 with (index=i1) where (col1 > 5 and col1 < 20) union all select col1 from t1 with (index=i2) where (col1 > 25 and col1 < 40)
Theme design by Jelle Druyts
Pick a theme: BlogXP sqlx BlogXP sqlx
Powered by: newtelligence dasBlog 2.0.7226.0
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2008, Conor Cunningham
E-mail