2010-07-12 129 views
3
declare @name varchar(156) 
set @name ='sara' 
--Query 1: 
SELECT [PNAME] FROM [tbltest] where [PNAME] like '%'[email protected]+'%' 

--Query 2: 
SELECT [PNAME] FROM [tbltest] where [PNAME] like '%sara%' 

假設[tbltest]的[PNAME]列中存在NoneClustered Index。 當運行查詢,Excution計劃顯示索引尋求查詢1和索引掃描查詢2. 我預計Excution Paln顯示索引掃描對於這兩個查詢,但由於使用第一個查詢中的參數,它顯示索引查找。 那麼我該怎麼做? 在這兩個查詢中,我們在另一側使用'%',並且知道在這種狀態下,sql不考慮索引 ,但爲什麼在第一個查詢計劃顯示索引查找? 謝謝Sql Excution Plan顯示對於相同輸入的不同結果

回答

0

如果您對錶和正在使用的索引執行DBCC SHOW_STATISTICS,請在輸出的第一行中查找「String Index = YES」。在第一個查詢中,您可能會看到計算的標量值 - 查看LikeRangeStart的查詢計劃('%'+ @ name +'% 「)。索引搜索是針對這些值而非針對%sara%的索引掃描。

這是如何工作我不知道。爲什麼SQL Server不夠聰明將'sara'轉換爲常量,並以與我不知道相同的方式執行查詢。但我認爲這就是發生了什麼。

針對%sara%,它執行索引掃描,讀取整個索引。針對%+ @ name +%,它會創建RangeStart/RangeEnd/RangeInfo計算值,並使用它們以某種方式執行索引查找,以利用附加字符串統計信息。

0

我認爲邁克是否在正確的軌道上是否擊中索引。您關於成本的後續行動可能需要更多瞭解您的數據在表格中的分佈情況。我看過一些實例,因爲需要兩個磁盤讀取操作,因此索引成本更高。要理解爲什麼,您必須知道您的數據如何在索引中分佈,有多少記錄適合頁面,以及您的緩存方案是什麼。

我會說,調整帶有前導%的查詢可能很困難。數據庫將需要完全遍歷您的索引(或表),並擊中每個節點尋找包含「sara」的值。根據您的需要,您可能需要考慮全文搜索(即使用此查詢中的參數值,因爲它是作爲應用程序用戶的輸入提供的)。

1

查詢一個使用參數,查詢2個常量。

如果更改常量值,則查詢2的計劃將不會重用。

計劃1的查詢可以是。在這種情況下,SQL Server(簡單地)將其選項打開以重用計劃。

AKA:查詢是不是相同。

如果force parameterisation,那麼你應該做兩個查詢運行像查詢1.不過我沒試過...

相關問題