我在我的數據庫這個存儲過程:SELECT不同的輸入對查詢速度有很大的影響?
ALTER PROCEDURE [dbo].[sp_FTSearchLocation]
@SearchFor nvarchar(200) = null
,@StartRow int
,@EndRow int
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM (
SELECT TOP (@EndRow)
*, ROW_NUMBER() OVER (ORDER BY Recommendations DESC, CompanyName) AS num
FROM
dbo.cachedSearchTable
WHERE
(
(@SearchFor IS NULL)
OR (CompanyName like '%' + @SearchFor + '%')
OR (Handle like '%' + @SearchFor + '%')
OR (Activity like '%' + @SearchFor + '%')
)
) As a
WHERE num > @StartRow
OPTION (RECOMPILE)
END
dbo.cachedSearchTable
與列Recommendations DESC, CompanyName
聚簇索引。沒有其他索引。我認爲使用*
是安全的,因爲表cachedSearchTable
被構建爲僅具有與該查詢相關的列。
對於某些搜索字符串,此過程運行速度非常快。例如,搜索accountants
的回報不到一秒鐘。但是,其他人運行速度非常緩慢:當@SearchFor
設置爲soup
時,大約需要6秒鐘才能返回。
每個這些執行計劃看起來是一樣的:
對於Accountants
:
ClusteredIndexScan (85%) ->
Segment (15%) ->
ComputeScalar (0%) ->
SequenceProject (0%) ->
Top (0%) ->
Filter (0%) ->
Select (0%).
對於Soup
:
ClusteredIndexScan (95%) ->
Parallelism (Gather Streams) (5%) ->
Segment (0%) ->
ComputeScalar (0%) ->
SequenceProject (0%) ->
Top (0%) ->
Filter (0%) ->
Select (0%).
然而,對於accountants
,該ClusteredIndexScan的估計運營商成本爲0.57,而soup
則成本爲25.34。
我試着在表格上放置3個非聚集索引 - 每個搜索列一個 - 但這沒有幫助。
我的數據庫中有很多會計師(〜4000),很少有他們名字中的「湯」(〜50)。一般來說,當有大量可能的結果可供選擇時,查詢運行得最快,而當返回的結果非常少時,查詢運行速度最慢。
如何加快此查詢?減慢寫入速度並不重要,但應用更多索引似乎沒有幫助。你能提出什麼建議嗎?
您是否嘗試更新統計信息?我使用類似的問題就像你的問題後,我把大量的記錄表table.I認爲統計碎片不會更新不正確,可能是SQL的原因得到錯誤的執行計劃。只是一個猜測 – 2012-02-15 16:44:00
它被稱爲參數嗅探 - 本質上,SQL Server根據您傳遞的第一個參數編譯計劃,但它可能會根據不同的參數做出不同的決定。你是否比較了好的和壞的執行的執行計劃?請參閱http:// stackoverflow。com/questions/1007397/sql-poor-stored-procedure-execution-plan-performance-parameter-sniffing and also get our free Plan Explorer tool which highlight these issues more better http://sqlsentry.net/plan-explorer/ sql-server-query-view.asp – 2012-02-15 16:44:28
@AaronBertrand謝謝,我會得到你的軟件,它看起來很有用。實際的存儲過程有很多額外的參數(全部可能爲空),所以它有'選項(重新編譯)'集合,我認爲這意味着每次重新編譯一個計劃。我編輯了我的問題來表明這一點。 – Oliver 2012-02-15 16:54:32