Ich speichere Sensordaten in einer Tabelle SensorValues . Die Tabelle und der Primärschlüssel lauten wie folgt:
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])
Wenn ich jedoch den Sensorwert auswähle, der für eine bestimmte Zeit gültig ist, teilt mir der Ausführungsplan mit, dass eine Sortierung durchgeführt wird. Warum das?
Ich hätte gedacht, dass die Sortierung nicht stattfinden würde, da ich die nach der Datumsspalte sortierten Werte speichere. Oder liegt es daran, dass der Index nicht nur nach der Datumsspalte sortiert ist, sondern nicht davon ausgehen kann, dass die Ergebnismenge sortiert ist?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
ORDER BY Date DESC
Edit: Kann ich das stattdessen machen?
Da die Tabelle nach DeviceId, SensorId, Date sortiert ist und ich ein SELECT durchführe , das nur eine DeviceId und eine SensorId angibt , sollte der Ausgabesatz bereits nach Date DESC sortiert sein . Ich frage mich also, ob die folgende Frage in allen Fällen das gleiche Ergebnis liefern würde.
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
Gemäß @Catcall unten stimmt die Sortierreihenfolge nicht mit der Speicherreihenfolge überein. Dh wir können nicht davon ausgehen, dass die zurückgegebenen Werte bereits sortiert sind.
Edit: Ich habe diese CROSS APPLY-Lösung ausprobiert, kein Glück
@ Martin Smith schlug vor, ich würde versuchen, mein Ergebnis auf die Partitionen anzuwenden. Ich fand einen Blogeintrag ( Ausgerichtete nicht gruppierte Indizes für partitionierte Tabellen ), in dem dieses ähnliche Problem beschrieben wurde, und versuchte die etwas ähnliche Lösung für das, was Smith vorgeschlagen hatte. Leider ist die Ausführungszeit mit meiner ursprünglichen Lösung vergleichbar.
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