Chr*_*uer 7 performance index sql-server nonclustered-index query-performance
我有一个Records
包含 100 多列和非常多行的表,以及基于我的访问路径的 5 个字段的非聚集索引:
CREATE NONCLUSTERED INDEX [IX_Records_CustomerID]
ON [dbo].[Records] (
[CustomerID] ASC, -- int
[IsInvalid] ASC, -- int
[IsProcessed] ASC, -- bit
[IsRejected] ASC, -- bit
[RecordName] ASC, -- varchar(12)
;
Run Code Online (Sandbox Code Playgroud)
这 5 个字段不包括主键RecordID
,它是聚集索引中的列。
这是我性能不佳的查询:
SELECT * FROM Records WHERE CustomerID IN (181, 283, 505)
Run Code Online (Sandbox Code Playgroud)
执行计划显示它执行聚集索引扫描,我理解这是因为我选择了未包含在索引中的列。在 Management Studio 中,我将查询更改为:
SELECT CustomerID, IsInvalid, IsProcessed, IsRejected, RecordName FROM Records
WHERE CustomerID IN (181, 283, 505)
Run Code Online (Sandbox Code Playgroud)
并且执行计划显示Index Seek,查询执行时间从44秒下降到2秒。但是,我在应用程序中缺乏自由,无法*
仅用我需要并包含在索引中的列替换。
当我被锁定时,有没有办法绕过聚集索引扫描SELECT *
?
如果您需要索引未涵盖的输出列,优化器必须做出选择:
它将选择哪种方式取决于多种因素,包括索引有多窄,与谓词匹配的行数等。您可以强制使用FORCESEEK
提示进行搜索,但我怀疑它最终会执行相同或更差的性能SQL Server 在您的情况下选择的扫描。
一些选项:
创建一个仅选择您需要的列的视图:
CREATE VIEW dbo.myview
WITH SCHEMABINDING
AS
SELECT col1, col2, col3 FROM dbo.tablename;
Run Code Online (Sandbox Code Playgroud)
然后您可以将应用程序更改为SELECT *
从此视图。或者您可以更有创意并重命名原始表,并将此视图的名称更改为该表以前的名称。显然,突破性的变化;谨慎行事。
将所有其他列添加到INCLUDE
索引的键或列表中。如果这些是硬编码值并且总是使用的值,您可以考虑过滤索引。
归档时间: |
|
查看次数: |
804 次 |
最近记录: |