这是破败:我在做一个选择查询。WHEREandORDER BY子句中的每一列都在一个非聚集索引中IX_MachineryId_DateRecorded,或者作为键的一部分,或者作为INCLUDE列。我正在选择所有列,因此将导致书签查找,但我只使用TOP (1),因此服务器肯定会告诉查找只需要在最后完成一次。
最重要的是,当我强制查询使用 index 时IX_MachineryId_DateRecorded,它会在不到一秒的时间内运行。如果我让服务器决定使用哪个索引,它会选择IX_MachineryId,并且最多需要一分钟。这真的向我表明我已经正确地建立了索引,而服务器只是做出了一个错误的决定。为什么?
CREATE TABLE [dbo].[MachineryReading] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Location] [sys].[geometry] NULL,
[Latitude] FLOAT (53) NOT NULL,
[Longitude] FLOAT (53) NOT NULL,
[Altitude] FLOAT (53) NULL,
[Odometer] INT NULL,
[Speed] FLOAT (53) NULL,
[BatteryLevel] INT NULL,
[PinFlags] BIGINT NOT NULL,
[DateRecorded] DATETIME NOT NULL,
[DateReceived] DATETIME NOT NULL,
[Satellites] INT NOT NULL,
[HDOP] FLOAT …Run Code Online (Sandbox Code Playgroud) 假设我有一个分区表,设置如下:
CREATE PARTITION FUNCTION PF_Month (DATE) AS RANGE RIGHT FOR VALUES (
'2017-01-01',
'2017-02-01',
'2017-03-01',
'2017-04-01',
'2017-05-01',
'2017-06-01',
);
GO
CREATE PARTITION SCHEME PS_Month AS PARTITION PF_Month ALL TO ([Primary]);
GO
CREATE TABLE Logs
(
Id INT NOT NULL,
DateRecorded DATE NOT NULL,
FixStatus INT NOT NULL
);
GO
ALTER TABLE Logs
ADD CONSTRAINT PK_Logs PRIMARY KEY (Id, DateRecorded)
ON PS_Month(DateRecorded);
GO
CREATE NONCLUSTERED INDEX [IX_DateRecorded] ON Logs(DateRecorded)
INCLUDE(FixStatus)
ON PS_Month(DateRecorded);
GO
Run Code Online (Sandbox Code Playgroud)
如果我想按日期顺序查询日志,我被告知我可以使用分区号以避免在每个分区的结果重新连接在一起时进行排序。
SELECT * FROM Logs WHERE ... ORDER …Run Code Online (Sandbox Code Playgroud) 我有一个表,它有一个聚集索引,如下所示:
CREATE CLUSTERED INDEX [IX_MachineryId_DateRecorded]
ON Machinery (MachineryId, DateRecorded)
Run Code Online (Sandbox Code Playgroud)
我根据聚集索引中的字段进行选择,再加上一个:
SELECT DateRecorded, Latitude, Longitude
FROM MachineryReading
WHERE MachineryId = 2127 -- First key in the index
AND DateRecorded > '2017-01-10' -- Second key in the index
AND DateRecorded < '2017-10-16' -- Second key in the index
AND FixStatus >= 2 -- Not a key, resulting in a scan
ORDER BY DateRecorded
Run Code Online (Sandbox Code Playgroud)
我原以为这会导致一个简单的聚集索引扫描。但是,查看实时查询统计信息和实际执行计划,查询的大部分执行时间来自对索引扫描后的结果进行排序。为什么排序后的数据又被排序了?
我只是遇到了必须在索引中包含一列的情况。这需要删除索引,然后重新创建它。这让我想到,这肯定是很多不必要的工作。
假设我先创建了新索引,然后删除了旧索引。让我们假设我有这表明旧索引将不会被丢弃,直到某种方式后,新的已创建了一个。
通过在创建新索引时使用旧索引,服务器会获得任何性能优势吗?