Estoy almacenando datos del sensor en una tabla SensorValues . La tabla y la clave primaria son las siguientes:
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])
Sin embargo, cuando selecciono el valor del sensor válido por un tiempo específico, el plan de ejecución me dice que está haciendo una especie. ¿Porqué es eso?
Pensé que, dado que almaceno los valores ordenados por la columna Fecha, la clasificación no se produciría. ¿O es porque el índice no está ordenado únicamente por la columna Fecha, es decir, no puede suponer que el conjunto de resultados está ordenado?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
ORDER BY Date DESC
Editar: ¿Puedo hacer esto en su lugar?
Dado que la tabla está ordenada DeviceId, SensorId, Date y hago un SELECT especificando solo un DeviceId y un SensorId , el conjunto de salida ya debería estar ordenado por Date DESC . Entonces, me pregunto si la siguiente pregunta arrojaría el mismo resultado en todos los casos.
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
Según @Catcall a continuación, el orden de clasificación no es el mismo que el orden de almacenamiento. Es decir, no podemos suponer que los valores devueltos ya están en un orden ordenado.
Editar: he probado esta solución CROSS APPLY, no tuve suerte
@ Martin Smith sugirió que intentara APLICAR EXTERIORMENTE mi resultado contra las particiones. Encontré una publicación de blog ( índices alineados no agrupados en una tabla particionada ) que describe este problema similar y probé una solución algo similar a lo que Smith sugirió. Sin embargo, no tuve suerte aquí, el tiempo de ejecución está a la par con mi solución original.
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