Sort order specified in primary key, yet sorting is executed on SELECT
For a non partitioned table I get the following plan
There is a single seek predicate on
Seek Keys: Prefix: DeviceId, SensorId = (3819, 53), Start: Date < 1339225010.
Meaning that SQL Server can perform an equality seek on the first two columns and then begin a range seek starting at
1339225010 and ordered
FORWARD (as the index is defined with
TOP operator will stop requesting more rows from the seek after the first row is emitted.
When I create the partition scheme and function
CREATE PARTITION FUNCTION PF (int) AS RANGE LEFT FOR VALUES (1000, 1339225009 ,1339225010 , 1339225011); GO CREATE PARTITION SCHEME [MyPartitioningScheme] AS PARTITION PF ALL TO ([PRIMARY] );
And populate the table with the following data
INSERT INTO [dbo].[SensorValues] /*500 rows matching date and SensorId, DeviceId predicate*/ SELECT TOP (500) 3819,53,1, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) FROM master..spt_values UNION ALL /*700 rows matching date but not SensorId, DeviceId predicate*/ SELECT TOP (700) 3819,52,1, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) FROM master..spt_values UNION ALL /*1100 rows matching SensorId, DeviceId predicate but not date */ SELECT TOP (1100) 3819,53,1, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) + 1339225011 FROM master..spt_values
The plan on SQL Server 2008 looks as follows.
The actual number of rows emitted from the seek is
500. The plan shows seek predicates
Seek Keys: Start: PtnId1000 <= 2, End: PtnId1000 >= 1, Seek Keys: Prefix: DeviceId, SensorId = (3819, 53), Start: Date < 1339225010
Indicating it is using the skip scan approach described here
the query optimizer is extended so that a seek or scan operation with one condition can be done on PartitionID (as the logical leading column) and possibly other index key columns, and then a second-level seek, with a different condition, can be done on one or more additional columns, for each distinct value that meets the qualification for the first-level seek operation.
This plan is a serial plan and so for the specific query you have it seems that if SQL Server ensured that it processed the partitions in descending order of
date that the original plan with the
TOP would still work and it could stop processing after the first matching row was found rather than continuing on and outputting the remaining 499 matches.
In fact the plan on 2005 looks like it does take that approach
I'm not sure if it is straight forward to get the same plan on 2008 or maybe it would need an
OUTER APPLY on
sys.partition_range_values to simulate it.
A lot of people believe that a clustered index guarantees a sort order on output. But that's not what it does; it guarantees a storage order on disk.
See, for example, this blog post, a follow-up, and this longer discussion.
I'm speculating that the SORT is needed because of parallel plan. I base this on some dim and distant blog article: but I found this on MSDN which may or may not justify this
So, try with MAXDOP 1 and see what happens...
Also hinted at in @sql kiwi's blog post on Simple Talk under "Exchange Operator" I think. And "DOP dependence" here