Sensör verilerini SensorValues tablosunda saklıyorum . Tablo ve birincil anahtar aşağıdaki gibidir:
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])
Ancak, belirli bir süre için geçerli olan sensör değerini seçtiğimde, yürütme planı bana bunun bir tür iş yaptığını söylüyor. Neden?
Tarih sütununa göre sıralanmış değerleri sakladığım için sıralama oluşmayacağını düşünürdüm. Yoksa, dizin yalnızca Tarih sütununa göre sıralanmadığı için mi, yani sonuç kümesinin sıralandığını varsayamaz mı?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
ORDER BY Date DESC
Düzenleme: Bunun yerine bunu yapabilir miyim?
Tablo DeviceId, SensorId, Date ve ben olarak sıralandığından, yalnızca bir DeviceId ve bir SensorId belirten bir SELECT yaparız , çıktı kümesi zaten Date DESC'e göre sıralanmalıdır . Yani merak ediyorum ki aşağıdaki soru her durumda aynı sonucu verir mi?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
Aşağıdaki @Catcall'a göre, sıralama düzeni depolama siparişiyle aynı değildir. Yani, döndürülen değerlerin zaten sıralanmış bir sırada olduğunu varsayamayız.
Düzenleme: Bu ÇAPRAZ UYGULAMA çözümünü denedim, şans yok
@Martin Smith, sonuçları bölümlere karşı DIŞI UYGULAMAYA çalışmayı önerdi. Bu benzer sorunu açıklayan bir blog yazısı ( bölümlenmiş tablodaki kümelenmemiş dizinleri hizalandı) buldum ve Smith'in önerdiğine biraz benzer bir çözüm denedim. Ancak, burada şans yok, yürütme süresi orijinal çözümümle eşit.
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