2012-03-22 71 views
1

我發現在我的某個存儲過程中似乎是瓶頸查詢。 @Results是約17K行的表變量。它包括一個TimeStamp(日期時間)列和一個值(十進制)列。相關的子查詢性能

相關的子查詢方法是我能想到的第一件事就是完成這個任務,但是性能很差。我想不出一種更好的方式來構建此查詢,而不是使用針對同一個表的相關子查詢來「計算」WHERE子句。任何建議如何可以寫得更好...

我基本上試圖從全部結果的子集中選擇最高值。現在,通過計算小於或等於該值的所有值,將其乘以100,並將其除以@Count,並查看它是否大於百分之一,來將結果記錄包括在子集中。

這裏的查詢:

SELECT TOP 1 @Result = Results.Value 
FROM @Results Results 
WHERE (100.0 * (SELECT COUNT(1) 
       FROM @Results Results2 
       WHERE Results2.Value <= Results.Value)/@Count) >= @Percent 
ORDER BY Results.Value ASC 

任何建議或幫助,將不勝感激。

謝謝!

+0

不,沒有Results.Value上的索引。結果是一個表變量。你可以添加一個索引到表變量嗎? – 2012-03-23 00:48:20

+1

看起來像你不能,除非你第一次創建時聲明PRIMARY KEY或UNIQUE約束:http://sqlserverplanet.com/sql/create-index-on-table-variable - 如果這不是一個選項,也許你應該首先在'#tempResults'表中存儲'@ Results',你可以*索引。 – 2012-03-23 04:41:38

回答

0

這將有助於更好地瞭解試圖實現什麼,用用戶領域而不是SQL來表達。

此外,所查詢的數據的整個範圍和結構都沒有給出,但可能包括涉及性能確定的關係。

首先,有這個結果表變量,它有它自己的派生。這種技術可能是有風險的,因爲它建立在通常是去優化器的隱式臨時表中。這就像你試圖向查詢優化器指定策略一樣。

看來你只是想要一個聚合查詢中的一個最大值,它應該是可優化的。實際上,只有17K條記錄甚至不會成爲優化問題。

SELECT MAX(Value) 
FROM some-aggregate-query 
GROUP BY fields 
HAVING COUNT(something)/COUNT(1) * 100 > @percent 

提示:

你能在形式重申這在我的經驗,你通常在朝着錯誤的方向,當你開始分解SQL(這正是程序上上策相反代碼)。

+0

感謝您的回覆。我特別感興趣的是你對關於table變量是「deoptimizer」的評論。你是否在意詳細說明?表變量通常不好?我實際上將上面的查詢轉換爲使用臨時表,標記爲TimeStamp作爲PK,在Value上創建了一個索引,執行時間降到了之前的三分之一。是什麼賦予了? – 2012-03-23 21:19:28

0

嗯這是怎麼回事:首先,選擇一個變量的行總數。接下來,您選擇索引處的行(@Percent/100.0 * countOfRowsTotal),按值排序。

這將掃描表1到2次。