Sql-Server
正確使用索引來優化查詢
我有一個包含數百萬條記錄的 SQL 數據庫,當我查詢數據時
select * from ActCosts where ScenarioID= 456
這些表有 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
使用索引查詢不會更快,因為 SQL Server 已確定執行聚群索引掃描比使用
IX_ActCost_ScenarioID
您定義的索引掃描並執行鍵查找來檢索所需的額外數據更有效。由於您只在 上定義了索引
ScenarioID
,沒有INCLUDE
列,因此您希望從查詢中返回的每個額外列都需要從聚集索引中檢索。在超過 50,000 行上,這根本不會是有效的,因此索引被忽略。首先,您需要問自己是否真的需要返回所有列。我不知何故懷疑你這樣做(例如 ID 列),但我可能錯了。 在任何情況下,您都應該始終定義列列表,而不是使用
*
.SELECT ActID, ActCostTypeID, Description, Cost, <rest_of_columns...> FROM dbo.ActCosts WHERE ScenarioID = 456;
注意:
然後,您需要包含返回的額外列
IX_ActCost_ScenarioID
:CREATE NONCLUSTERED INDEX [IX_ActCost_ScenarioID] ON [dbo].[ActCost] ([ScenarioID] ASC) INCLUDE ( <list_all_other_columns_returned> ); GO