Saya menyimpan data sensor dalam tabel Nilai Sensor . Tabel dan kunci utama adalah sebagai berikut:
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])
Namun, ketika saya memilih nilai sensor yang valid untuk waktu tertentu, rencana eksekusi memberitahu saya itu sedang melakukan semacam. Mengapa demikian?
Saya akan berpikir bahwa karena saya menyimpan nilai yang diurutkan berdasarkan kolom Date, pengurutan tidak akan terjadi. Atau apakah itu karena indeks tidak hanya diurutkan berdasarkan kolom Tanggal, artinya tidak dapat berasumsi bahwa set hasil diurutkan?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
ORDER BY Date DESC
Sunting: Bisakah saya melakukan ini?
Karena tabel diurutkan DeviceId, SensorId, Date dan saya melakukan SELECT menentukan hanya satu DeviceId dan satu SensorId , output yang ditetapkan harus sudah diurutkan berdasarkan Date DESC . Jadi saya bertanya-tanya apakah pertanyaan berikut akan menghasilkan hasil yang sama dalam semua kasus?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
Menurut @Catcall di bawah ini, urutan pengurutan tidak sama dengan urutan penyimpanan. Yaitu kita tidak dapat mengasumsikan bahwa nilai yang dikembalikan sudah dalam urutan diurutkan.
Sunting: Saya sudah mencoba solusi CROSS APPLY ini, tidak berhasil
@ Martin Smith menyarankan saya akan mencoba LUAR MENERAPKAN hasil saya terhadap partisi. Saya menemukan posting blog ( Indeks non-clustered disejajarkan pada tabel dipartisi ) menggambarkan masalah yang sama dan mencoba solusi yang agak mirip dengan apa yang disarankan Smith. Namun, tidak beruntung di sini, waktu eksekusi setara dengan solusi asli saya.
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