gpt4 book ai didi

sql-server - 为什么 SQL Server 不使用我的索引?

转载 作者:行者123 更新时间:2023-12-02 00:05:27 25 4
gpt4 key购买 nike

在我们的数据库中,我们有这个包含 200.000 行的表

CREATE TABLE dbo.UserTask (
UserTask_ID int NOT NULL IDENTITY (1, 1),
UserTask_SequenceNumber int NOT NULL DEFAULT 0,
UserTask_IdEntitat uniqueidentifier NOT NULL,
UserTask_Subject varchar(100) NOT NULL,
UserTask_Description varchar(500) NOT NULL,
.....
.....
CONSTRAINT [PK_UserTask] PRIMARY KEY CLUSTERED
(
[UserTask_ID] ASC
) ON [PRIMARY]
) ON [PRIMARY]

我已在 UserTask_IdEntitat 列上创建了索引

CREATE NONCLUSTERED INDEX IX_UserTask_IDEntitat ON dbo.UserTask 
(
UserTask_IDEntitat
)

执行以下查询,执行计划向我们显示 UserTask_IDEntitat 上的索引用于执行查询:

SELECT UserTask_ID
FROM UserTask
WHERE UserTask_IdEntitat = @IdEntitat
ORDER BY UserTask_LastSendSystemDateTime desc

但是如果我们在Select列表中添加另一列,则不会使用索引

SELECT UserTask_ID, UserTask_SequenceNumber, UserTask_IDEntitat, ....., UserTask_Subject
FROM UserTask
WHERE UserTask_IdEntitat = @IdEntitat
ORDER BY UserTask_LastSendSystemDateTime desc

为什么添加与主键不同的列会导致 SQL Server 执行计划不使用 UserTask_IDEntitat 列上的索引?

点击此链接http://bytes.com/topic/sql-server/answers/144592-sqlsever-not-using-index似乎过滤值在列上重复的次数,它可以使索引不被使用,但我尝试使用重复 60.000 次的 @IdEntitat 值和仅重复的其他值进行查询175 次结果相同,IDEntitat 列上的索引被忽略。

这让我发疯了!

感谢您的帮助。

最佳答案

好的 - 只要您只选择索引中的列,或者集群键中的某些内容(通常,这是主键),那么就会使用索引,因为 SQL Server 可以找到它的所有信息索引导航结构的叶级别中需要(UserTask_IDEntitat 列和聚集索引列)。因此它可以直接从索引的叶级页面返回 SELECT 查询所需的数据。

但是:如果您需要选择第二列,即既不是索引定义中的列,也不是集群键的一部分,那么 SQL Server 必须对实际数据页执行所谓的书签查找

因此对于它在非聚集索引中找到的每一行,它必须采用聚集索引值,搜索聚集索引以找到实际的数据页该聚集索引的叶级别,然后选择所需的一列。

书签查找非常适合少量的点击 - 如果您选择数千行,它们对性能来说是完全毁灭性的。在这种情况下,SQL Server 查询优化器正确地使用聚集索引扫描 - 因为在聚集索引中,在叶级别,它可以立即使用所有行 .

所以:如果您在 UserTask_IDEntitat 上有索引,并且有时也需要第二列 UserTask_SequenceNumber - 那么您可以包含该列你的非聚集索引:

CREATE NONCLUSTERED INDEX IX_UserTask_IDEntitat 
ON dbo.UserTask(UserTask_IDEntitat)
INCLUDE(UserTask_SequenceNumber)

这样,该附加列仅出现在该非聚集索引的叶级中(它不能在 WHERE 子句中使用 - 它不是索引的导航结构!) - 并且您的第二个 SELECT 可以再次从非聚集索引的叶级节点得到满足 -> 不需要昂贵的书签查找 -> 将再次使用您的索引.

长话短说:除非您的非聚集索引具有高度选择性(例如返回 1% 或更少的行),并且除非您的非聚集索引是一个覆盖索引(包含满足特定查询所需的所有列的索引),那么变化非常大,SQL Server将使用您的非聚集索引.

了解更多信息:

关于sql-server - 为什么 SQL Server 不使用我的索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17858949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com