Sql-Server

正確使用索引來優化查詢

  • May 13, 2020

我有一個包含數百萬條記錄的 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;

注意:

1.不要避免使用模式前綴

2.避免使用SELECT *

然後,您需要包含返回的額外列IX_ActCost_ScenarioID

CREATE NONCLUSTERED INDEX [IX_ActCost_ScenarioID] ON [dbo].[ActCost] ([ScenarioID] ASC)
INCLUDE ( <list_all_other_columns_returned> );
GO

引用自:https://dba.stackexchange.com/questions/86748