sql-server - BIT 非选择性列上的 SQL Server 索引
问题描述
我们有很多列(80+)的非常大的表(300k 行)。其中一列是一个位字段,用于标记该行是否被删除:
CREATE TABLE [dbo].[tblProject]
(
[Id] [INT] IDENTITY(1,1) NOT NULL,
...
[Deleted] [BIT] NOT NULL,
CONSTRAINT [PK_tblProject]
PRIMARY KEY CLUSTERED ([Id] ASC) ON [PRIMARY]
)
一些不再与我们合作的开发人员在Deleted
列上创建了 3 个索引:
CREATE NONCLUSTERED INDEX [IX_tblProject_Deleted]
ON [dbo].[tblProject] ([Deleted] ASC)
INCLUDE ([Id], [FK1Id], [FK2Id], [FK3Id], [SomeDecimalColumn]) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_tblProject_Deleted2]
ON [dbo].[tblProject] ([Deleted] ASC)
INCLUDE ([Id], [FK1Id], [FK2Id], [FK4Id], [FK5Id]) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_tblProject_Deleted3]
ON [dbo].[tblProject] ([Deleted] ASC)
INCLUDE ([Id], [FK1Id], [FK2Id], [FK4Id]) ON [PRIMARY]
我的第一个问题是——第三个索引似乎完全被索引 2 覆盖了。我说这样的索引没有带来任何有价值的东西并且可以被删除是对的吗?
列的数据分布Deleted
如下所示:
99.9% rows contain 0
0.1% rows contain 1
我们有很多tblProject
关于各种外键的查询,它们都包含WHERE Deleted = 0
子句。如您所见,此谓词几乎不会从工作集中删除任何行。
据我所知和以下链接:
查询优化器永远不会使用这些索引,因为这些索引的使用根本不会减少工作集。执行表扫描比读取索引更有效。
WHERE Deleted = 1
如果我们的查询包含子句,它们将很有用。但他们没有。
那么所有这些索引都可以安全删除吗?
或者查询优化器是否足够聪明,可以使用索引快速找到 Deleted=1 的行,然后将它们从工作集中删除以实现 Deleted=0?
我无法检查系统中的所有查询以确认未使用索引。我想删除这些索引,但我不想降低系统性能。删除它们会对性能产生负面影响吗?
解决方案
推荐阅读
- sql - 如何在不转储的情况下更改 postgresql 中列的位置
- docker - 使用外部文件构建 Docker
- php - 如何使用php从mongodb文档中删除或删除数组数据
- excel - 工作表类的运行时错误“1004”粘贴方法失败(仅在选定的计算机上)
- mongodb - 删除具有对象键值猫鼬的数组元素
- php - 警告:array_column() 期望参数 1 为数组,在
- python - Plotly choropleth 在在线但不在离线模式下工作
- angular - 更新 Firebase 和 Angular 后获取“firebase.auth 不是函数”
- python - Deleting an element from a list of tuples and then calculating a total price based on elements within each tuple
- python-3.x - 如何区分物体曲率的两种不同类型的异常?