【发布时间】:2022-01-04 11:41:08
【问题描述】:
我有两张桌子
[dbo].[Employee](
[EmployeeID] [int] IDENTITY(1,1) NOT NULL,
[Title] [varchar](50) NULL,
[Role] [int] NULL,
[Status] [varchar](1) NULL)
[dbo].[Roles](
[id] [int] IDENTITY(1,1) NOT NULL,
[Role] [varchar](25) NULL,
[Description] [varchar](25) NULL)
通过 id 使用主集群键。 我也有存储过程
SELECT
[EmployeeID]
,[Title]
,employee.[Role]
,roles.Role AS RoleName
FROM [dbo].Employee AS employee
INNER JOIN [dbo].Roles AS roles ON roles.id = employee.Role
WHERE [Status] <> 'D'
执行计划向我展示了我想要避免的“聚集索引扫描”。有什么办法可以将其转换为“聚集索引搜索”? Execution Plan screen
db fiddle>
【问题讨论】:
-
不是那个查询,不是。
CLUSTERED INDEX在id上(我假设EmployeeID),但您正在过滤Status的值。如果您在status上有一个覆盖索引,RDBMS 可以使用它来查找,尽管考虑到您使用的是<>,它可能选择不这样做。 -
步骤1)添加角色外键。
-
您可以尝试过滤索引
Employee (Role, EmployeeID) INCLUDE (Status, Title) WHERE (Status <> 'D')。如前所述,这里不需要加入,如果你有外键,就会被省略 -
学习良好的习惯。不要不一致地使用括号。除非绝对必要,否则我建议您不要使用它们,因为它们会使您的代码难以阅读。通常 SELECT 查询应该有一个 ORDER BY 子句。请使用语句终止符。具有除标识主键列之外的所有可为空列的表在逻辑上存在缺陷。 1 个字符的列究竟是什么变量?想想你的数据类型。
-
@SMor "一般
SELECT查询应该有一个ORDER BY子句" 你从哪里得到的?是的,如果客户端应用程序期望行按他们应该指定的特定顺序排列,但应用程序应该被编写为对顺序不可知并且不应该关心,这减少了服务器上不必要的排序。同意其余的
标签: sql sql-server indexing sql-execution-plan