是什么驱使SQL Server对返回6000多行的查询使用不太优化的执行计划?我需要提高返回所有行的方案的查询性能。
我选择所有字段并在索引中包含的相同三列上添加排名。根据返回的行数,查询有两个不同的执行计划,因此执行时间分别为0.2秒或3秒。
从1行返回到ca. 5000查询运行速度很快。从6000行返回到所有,查询运行缓慢。
var inputElementRect = document.getElementById('YOURINPUTID').getBoundingClientRect()
var width = inputElementRect.left - caretRect.left
有约。 38000行。数据库在Azure SQL v12上运行。
表:
Table1
查询:
CREATE TABLE [dbo].[Table1](
[ID] [int] IDENTITY(1,1) NOT NULL,
[KOD_ID] [int] NULL,
[SYM] [nvarchar](20) NULL,
[AN] [nvarchar](35) NULL,
[A] [nvarchar](10) NULL,
[B] [nvarchar](2) NULL,
[C] [datetime] NULL,
[D] [datetime] NULL,
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
CREATE NONCLUSTERED INDEX [IX_Table1] ON [dbo].[Table1]
(
[KOD_ID] ASC,
[SYM] ASC,
[AN] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
两个查询的执行计划
答案 0 :(得分:2)
CREATE NONCLUSTERED INDEX [IX_Table1] ON [dbo].[Table1]
(
[KOD_ID] ASC,
[SYM] ASC,
[AN] ASC
) INCLUDE ([A], [B], [C], [D]);
创建这种覆盖索引,它应该扫描这个索引,甚至不需要排序,因为它的数据已经在索引中排序。
您的查询中的关键点是:
如果您正好进行索引重建并支持读取插入,那么这些可能是您的表的备用DDL,而KOD_ID
,SYM
,AN
不能为空:
如果需要ID
来确保唯一性:
CREATE TABLE [dbo].[Table1] (
[KOD_ID] [int] NOT NULL
, [SYM] [nvarchar](20) NOT NULL
, [AN] [nvarchar](35) NOT NULL
, [ID] [int] IDENTITY(1, 1) NOT NULL
, [A] [nvarchar](10) NULL
, [B] [nvarchar](2) NULL
, [C] [datetime2] NULL
, [D] [datetime2] NULL
, CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED ([KOD_ID], [SYM], [AN], [ID])
);
GO
如果不需要ID
来确保唯一性:
CREATE TABLE [dbo].[Table1] (
[KOD_ID] [int] NOT NULL
, [SYM] [nvarchar](20) NOT NULL
, [AN] [nvarchar](35) NOT NULL
, [A] [nvarchar](10) NULL
, [B] [nvarchar](2) NULL
, [C] [datetime2] NULL
, [D] [datetime2] NULL
, CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED ([KOD_ID], [SYM], [AN])
);
GO
另请注意,我使用datetime2
代替datetime
,这是Microsoft建议的:https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetime-transact-sql
使用时间,日期, datetime2 和 datetimeoffset 数据 新工作的类型。这些类型与SQL标准一致。他们是 更便携。 时间, datetime2 和 datetimeoffset 提供 更精确的秒数。 datetimeoffset 提供时区支持 用于全球部署的应用程序。