센서 데이터를 테이블 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])
그러나 특정 시간 동안 유효한 센서 값을 선택하면 실행 계획에 따라 정렬 중임을 알려줍니다. 왜 그런 겁니까?
Date 열로 정렬 된 값을 저장하므로 정렬이 수행되지 않을 것이라고 생각했을 것입니다. 아니면 인덱스가 날짜 열만 기준으로 정렬되지 않았기 때문에, 즉 결과 집합이 정렬되었다고 가정 할 수 없습니까?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
ORDER BY Date DESC
편집 : 대신 할 수 있습니까?
테이블이 DeviceId, SensorId, Date 로 정렬되어 있고 하나의 DeviceId 및 하나의 SensorId 만 지정 하여 SELECT 를 수행 하므로 출력 세트는 이미 Date DESC 로 정렬되어야합니다 . 그래서 다음 질문이 모든 경우에 동일한 결과를 낼지 궁금합니다.
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = 3819
AND Date < 1339225010
아래 @Catcall에 따르면 정렬 순서는 저장 순서와 다릅니다. 즉, 반환 된 값이 이미 정렬 된 순서라고 가정 할 수 없습니다.
편집 : 나는이 CROSS APPLY 솔루션을 시도했지만 운이 없다.
@Martin Smith는 파티션에 대한 결과를 외부에 적용하려고 시도했습니다. 이 비슷한 문제를 설명 하는 블로그 게시물 ( 파티션 된 테이블의 정렬 된 비 클러스터형 인덱스 )을 발견하고 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