Viv*_*ekh 3 performance index sql-server azure-sql-database performance-tuning
我有一个包含数百万条记录的 SQL 数据库,当我查询数据时
select * from ActCosts where ScenarioID= 456
Run Code Online (Sandbox Code Playgroud)
这些表有 1,323,718 行,它给了我 50,000 多行,这令人惊讶地花费了 3 多分钟。所以我现在正在考虑如何改进这个性能。我发现一种方法是在“SomeID”列上创建索引。我已经创建了这个索引,但查询需要相同的时间

执行计划

索引脚本
CREATE NONCLUSTERED INDEX [IX_ActCost_ScenarioID] ON [dbo].[ActCost]
(
[ScenarioID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
ALTER TABLE [dbo].[ActCost] ADD CONSTRAINT [PK_ActCost] PRIMARY KEY CLUSTERED
(
[ActCostID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
Run Code Online (Sandbox Code Playgroud)
使用索引查询并不会更快,因为 SQL Server 已确定执行聚集索引扫描比使用IX_ActCost_ScenarioID您定义的并执行键查找来检索所需的额外数据更有效。
由于您只在 上定义了索引ScenarioID,没有INCLUDE列,因此您希望从查询返回的每个额外列都需要从聚集索引中检索。在 50,000+ 行上,这根本不会有效,因此索引被忽略。
首先,您需要问自己是否真的需要返回所有列。我以某种方式怀疑你这样做(例如 ID 列),但我可能是错的。 在任何情况下,您都应该始终定义列列表而不是使用*.
SELECT
ActID,
ActCostTypeID,
Description,
Cost,
<rest_of_columns...>
FROM dbo.ActCosts
WHERE ScenarioID = 456;
Run Code Online (Sandbox Code Playgroud)
注意:
1.不要避免使用schema 前缀
2.避免使用SELECT *
然后,您需要包含在 中返回的额外列IX_ActCost_ScenarioID:
CREATE NONCLUSTERED INDEX [IX_ActCost_ScenarioID] ON [dbo].[ActCost] ([ScenarioID] ASC)
INCLUDE ( <list_all_other_columns_returned> );
GO
Run Code Online (Sandbox Code Playgroud)