Ing*_*ond 0 sql-server execution-plan
我的桌子是这样的:
CREATE TABLE [dbo].[ClosedTaskCustomFields](
[ClosedTaskId] [uniqueidentifier] NOT NULL,
[CustomFieldId] [uniqueidentifier] NOT NULL,
[Value] [nvarchar](450) NULL
...
CONSTRAINT [PK_ClosedTaskCustomFields] PRIMARY KEY CLUSTERED
(
[ClosedTaskId] ASC,
[CustomFieldId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
我也有这样的索引用于连接 ClosedTask 表:
CREATE NONCLUSTERED INDEX [IX_ClosedTaskCustomFields_ClosedTaskId] ON [dbo].[ClosedTaskCustomFields]
(
[ClosedTaskId] 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, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么这样的查询会读取所有 ClosedTaskCustomFields 表以加入 ClosedTask(如果我有索引)。
select count(1) from ClosedTaskCustomFields ctcf
join ClosedTask c on c.id = ctcf.ClosedTaskId
where c.State = 'Rejected'
-- Result count is 50k.
Run Code Online (Sandbox Code Playgroud)
SQL Server 根据其估计选择看起来最便宜的计划。这意味着您想要的计划(在两个表上都进行索引查找)的成本会更高。您可以使用提示自行测试这一点FORCESEEK。
请注意,较高的估计成本并不一定意味着该计划的执行速度会比在特定硬件上选择的替代方案慢。
\n该计划成本较低的原因有很多:
\n您可能会发现优化器自然会选择带有提示的搜索计划,或者通常会选择MAXDOP 1更高的并行成本阈值。似乎您已将其设置为默认值 5,如今许多人认为该值太低了。
否则,您将只能使用诸如 之类的提示来覆盖优化器选择\xe2\x80\x94 的正常方法FORCESEEK。除非查询至关重要并且节省几毫秒的时间很重要,否则我不会打扰。
有关行模式位图的更多信息,请参阅我的文章Bitmap Magic(或\xe2\x80\xa6 SQL Server 如何使用位图过滤器)。
\n