我将传感器数据存储在表SensorValues中。该表和主键如下:
CREATE TABLE [dbo].[SensorValues](
[DeviceId] [int] NOT NULL,
[SensorId] [int] NOT NULL,
[SensorValue] [int] NOT NULL,
[Date] [int] NOT NULL,
CONSTRAINT [PK_SensorValues] PRIMARY KEY CLUSTERED
(
[DeviceId] ASC,
[SensorId] ASC,
[Date] DESC
) WITH (
FILLFACTOR=75,
DATA_COMPRESSION = PAGE,
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF,
ONLINE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON)
ON [MyPartitioningScheme]([Date])
但是,当我选择在特定时间内有效的传感器值时,执行计划会告诉我它正在执行排序。这是为什么?
我以为,由于我存储了按日期列排序的值,因此不会发生排序。还是因为索引不是仅按“日期”列排序,即不能假设结果集已排序?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
ORDER BY Date DESC
编辑:我可以代替吗?
由于该表已排序为DeviceId,SensorId,Date,并且我执行了仅指定一个DeviceId和一个SensorId的SELECT,因此输出集应已按Date DESC排序。因此,我想知道以下问题在所有情况下是否都能产生相同的结果?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
根据下面的@Catcall,排序顺序与存储顺序不同。即,我们不能假设返回的值已经按排序顺序。
编辑:我已经尝试过这种交叉应用解决方案,没有运气
@Martin Smith建议我尝试将结果对分区进行外部应用。我发现了一篇博客文章(分区表上的对齐的非聚集索引)描述了类似的问题,并尝试了与Smith所建议的方案类似的解决方案。但是,这里没有运气,执行时间与我原来的解决方案相当。
WITH Boundaries(boundary_id)
AS
(
SELECT boundary_id
FROM sys.partition_functions pf
JOIN sys.partition_range_values prf ON pf.function_id = prf.function_id
WHERE pf.name = 'PF'
AND prf.value <= 1339225010
UNION ALL
SELECT max(boundary_id) + 1
FROM sys.partition_functions pf
JOIN sys.partition_range_values prf ON pf.function_id = prf.function_id
WHERE pf.name = 'PF'
AND prf.value <= 1339225010
),
Top1(SensorValue)
AS
(
SELECT TOP 1 d.SensorValue
FROM Boundaries b
CROSS APPLY
(
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND "Date" < 1339225010
AND $Partition.PF(Date) = b.boundary_id
ORDER BY Date DESC
) d
ORDER BY d.Date DESC
)
SELECT SensorValue
FROM Top1