Я зберігаю дані датчиків у таблиці 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 та I SELECT із зазначенням лише одного DeviceId та одного SensorId , набір вихідних даних вже повинен бути відсортований за датою DESC . Тож мені цікаво, чи дасть наступне запитання однаковий результат у всіх випадках?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
Відповідно до @Catcall нижче, порядок сортування не такий, як порядок зберігання. Тобто ми не можемо припустити, що повернені значення вже впорядкованому порядку.
Редагувати: Я спробував це CROSS APPLY рішення, не пощастило
@Martin 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