Sql-Server
為什麼此列有排序
此查詢有一個包含 SORT 的計劃,並且排序佔用了大部分 (77%) 成本:
SELECT LFTYLM_STATUS FROM LFTYLM WHERE LFTYLM_LIS_ID = 138998 AND LFTYLM_LFTY_ID = 78 AND ((LFTYLM_STATUS = 'A' AND (LFTYLM_DATE_INCLUDED_LAST IS NULL OR '1/1/2022' >= LFTYLM_DATE_INCLUDED_LAST)) OR (LFTYLM_STATUS = 'I' AND ('1/1/2022' >= LFTYLM_DATE_INCLUDED_LAST OR LFTYLM_DATE_INCLUDED_LAST IS NULL OR LFTYLM_DATE_INCLUDED_LAST < LFTYLM_DATE_UPDATED))) ORDER BY CASE WHEN (LFTYLM_STATUS = 'A') THEN 1 ELSE 2 END ASC, CASE WHEN (LFTYLM_DATE_INCLUDED_LAST <= '1/1/2022') THEN DATEDIFF(DAY, '1/1/2022', CURRENT_TIMESTAMP) ELSE -9999 END DESC
該計劃位於: https ://www.brentozar.com/pastetheplan/?id=BktHa062K
為什麼 LFTYLM_STATUS 上有 SORT?
正在使用的索引包括 LFTYLM_STATUS 作為鍵列:
CREATE NONCLUSTERED INDEX [IX_LISTING_FEED_TYPE_LISTING_MAP_5] ON [dbo].[LISTING_FEED_TYPE_LISTING_MAP] ( LFTYLM_LIS_ID ASC, LFTYLM_LFTY_ID ASC, LFTYLM_DATE_INCLUDED_LAST ASC, LFTYLM_DATE_UPDATED ASC, LFTYLM_STATUS ASC ) WITH (FILLFACTOR = 95)
不
即使有完美的索引,SQL Server也無法利用它們來避免對數據進行物理排序,就像 where 子句的編寫方式一樣。
這個問題在您的查詢計劃中很明顯,因為您不是按列排序,而是按表達式排序。
製作像這樣可索引的表達式的唯一方法是:
- 製作計算列,並為它們編制索引
- 創建索引視圖,並對結果列進行索引
否則,SQL Server 將不得不在執行時計算這些 case 表達式並對結果進行排序。
在旁邊
由於我看到您愛上了成本模因,因此我將在此處重複部分答案。
我看到你經常談論成本,並降低成本。請不要關注成本。這是一個無單位的估計指標,與查詢的哪些部分緩慢且效率低下無關。
請注意,當您獲得實際執行計劃時,沒有“實際”成本。即使在 SQL Server 測量和報告許多其他執行時(實際)指標之後,它們仍然是估計值。
優化器使用成本快速選擇一個足夠好的計劃。減少它們不一定會讓您獲得更快的查詢。您可以有快速執行的昂貴查詢和執行緩慢的廉價查詢。
我建議查看操作員時間以確定哪些部分效率最低。
您有包含 LFTYLM_STATUS 和 LFTYLM_DATE_INCLUDED_LAST 的 ORDER BY 子句,因此對這兩列都進行了排序。
ORDER BY CASE WHEN (LFTYLM_STATUS = 'A') THEN 1 ELSE 2 END ASC, CASE WHEN (LFTYLM_DATE_INCLUDED_LAST <= '1/1/2022') THEN DATEDIFF(DAY, '1/1/2022', CURRENT_TIMESTAMP) ELSE -9999 END DESC