cod*_*ool 15 performance index database-agnostic
我的问题是关于索引的使用。
我应该从一开始还是在出现性能问题时开始索引?
我们还可以在执行查询时创建临时索引。这种技术的优缺点是什么?
Mar*_*ith 17
我应该从一开始还是在出现性能问题时开始索引?
索引策略往往会随着使用模式的出现而发展。也就是说,也有可以预先应用的策略和设计指南。
选择一个好的聚类键。您通常可以在设计时根据预期的表插入模式确定适当的聚集索引。如果出现令人信服的案例来说明未来的变化,那就随它去吧。
创建您的主要约束和其他唯一约束。这些将由唯一索引强制执行。
创建外键和关联的非聚集索引。外键是你最常引用的连接列,所以从一开始就索引它们。
为任何明显高度选择性的查询创建索引。对于您已经知道的查询模式,将具有高度选择性,并且可能使用查找而不是扫描。
除上述之外,采取渐进和整体的方法来实施新索引。通过整体,我的意思是在评估添加时评估对所有查询和现有索引的潜在好处和影响。
由于缺少索引 DMV 和 SSMS 提示的指导,SQL Server 圈子中一个并不少见的问题是过度索引。这些工具都不会评估现有索引,并且会很高兴地建议您创建一个新的 6 列索引,而不是将单个列添加到现有的 5 列索引中。
-- If you have this
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
)
-- But your query would benefit from the addition of a column
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
, [col6] ASC
)
-- SSMS will suggest you create this instead
CREATE NONCLUSTERED INDEX [IX_MyTable_AnotherIndexWithTheSameColumnsAsTheExistingIndexPlusCol6] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
, [col6] ASC
)
Run Code Online (Sandbox Code Playgroud)
Kimberly Tripp有一些关于索引策略的优秀材料,虽然 SQL 重点适用于其他平台。对于 SQL Server 人员,有一些方便的工具可用于识别重复项,如上面的示例。
我们还可以在执行查询时创建临时索引。这种技术的优缺点是什么?
这通常仅适用于很少运行的查询,通常是 ETL。您需要评估:
这两种方法确实存在风险:
选项 a)从一开始就建立索引,但没有意识到您已经创建了许多从未使用过的索引。这些增加了一些开销(最明显的是修改数据的查询,但也优化了试图识别最佳索引的 SELECT 语句)。
您需要自律以识别不再使用的索引并尝试删除它们(PostgreSQL 可以做到这一点;不幸的是,相比之下 MySQL 在这方面非常弱。)
选项 b)在人们开始抱怨之前不要添加索引,或者您的诊断工具触发某些查询很慢并且可以改进。
您引入的风险是在您注意到需要索引和必须添加索引之间没有足够大的时间窗口。
PostgreSQL 确实支持构建索引CONCURRENTLY
,这确实减轻了这种突然索引添加要求带来的压力,但是手册中有一些注意事项。
选项 (b) 往往是我的偏好,但我认为这两种选项的混合可能是最好的解决方案。这与您是否认为索引会被实际使用有关的信心水平有关。
使这成为一个特别复杂的讨论的是,更改索引通常很容易,但更改架构却很难。我不想宣传b的反应迟钝作为鲁莽的借口。