2015-06-24 40 views
1

短簡介:優化SQL計算序列 - 嵌套查詢還是單獨查詢?

當需要具有嵌套計算查詢一打,就是它更優化到

  • A)單獨執行每個操作(保存到一個表中的每個結果然後讀取用於下一個查詢表)
  • B)有一大組嵌套選擇
的3210

完整說明:

我試圖從SQL一系列輸入表的計算一些先進的預測。

我正在構建圍繞着十幾個「模塊」分離成自己的模式,每個模塊通常包括4-10個輸入表和6-10個計算步驟。一旦完成,每個模塊的所有輸出都被轉儲到同一個輸出表中。

查詢範圍從7k-200k行。

單個模式的/模塊的表可能看起來像這樣:

  • 輸入表1
  • 輸入表2
  • 輸入表3
  • 輸入表4
  • 計算查詢1個結果表
  • 計算查詢2結果表
  • Calculati上查詢3結果表
  • 計算查詢4結果表
  • 計算查詢5結果表
  • 計算查詢6結果表

  • 最終輸出

每個計算查詢使用的結果(大部分)。最終輸出是最終計算查詢的結果。計算不是很複雜:最大分割,基本公式(+, - ,*,/)或SUM等。正常情況下,每個計算步驟中只有這些中的1-3個總是在同一列上。

這是拆分爲多個計算查詢(而不是一個超級公式)的主要原因是每個計算以不同的方式連接輸出並使用不同的輸入表;也因爲有些基於上一行結果。 (如MAX分區或滯後)

我的要求如下:

  • ,其計算來自步驟1的最終輸出和合併到最終輸出的過程。
  • 一個計算直到所選計算查詢併合併到其各自結果表(並停止)的過程。考慮這次「壓倒一切的最後的」

DONT需要存儲中間查詢的計算結果 - 僅最終的輸出或「壓倒一切的最後的」如果選擇。

我的問題: 我想優化整個過程 - 在這一點上它看起來將需要大約10-15秒。我希望它是1秒 - 但我很欣賞這可能是不可能的。

我曾嘗試:

首先,我創建該合併的結果到其相應的輸出表中的每個計算查詢的單個過程。使用這種方法,每個計算查詢必須從數據庫中讀取,然後合併到其輸出中。

我試過臨時表,但是我不明白爲什麼這會是最優的,因爲我已經有了計算步驟的表格 - 這些表格已經考慮到了下一步的索引。

然後,我做了一個假設,將所有查詢嵌套到一個超級過程或者甚至可以有一系列表函數會更快。

我的問題:

但是我遇到了一個想法,我無法找到一個答案 - 這是以下幾點:

  • 插入結果到一個表上的每一個計算步驟可能會放緩該過程(特別是因爲他們被索引2-4列);但至少數據將被編入索引爲下一步。
  • 嵌套選擇將節省插入數據的努力,但這些結果不會被索引?對?還是錯了?

智能索引的選擇結果是?考慮到我的情況,你會告訴我如何處理這個問題。也許我錯過了一些非常簡單的事情。

附加信息:

  • 我的大部分大的查詢結果(150-200K)有4列需要建立索引。
  • 我所有的表格只有一列需要計算 - 其餘的都是索引的。

例如: ForecastID,集團年,類型,子類型,值

所以我要指標組,年,類型和子類型來加入多個輸入表,然後計算出上值列。

我告訴你,如果索引繁重的表影響你的建議 - 我不會在這裏尋求優化索引的幫助,因爲已經有大量的建議可用,因爲這是一個不同的問題!

+0

如果您可以顯示一些輸入和輸出,您將得到更多回復。 – LoztInSpace

回答

2

查詢優化通常比科學更具藝術性,因爲對結果有太多可能的影響,所以很少有硬性規則和快速規則。有了這個大的警告,時間到了高點。

索引對加載表的影響 - 索引對插入的性能影響與觸發器類似。除非你有一個篩選索引,否則每個插入將不得不更新表上的每個索引,因此在三個索引中,你正在查看每插入更新的數量的四倍。在每插入一次讀取和200k的小表格(非常適用於表格掃描)的情況下,對於三個索引,您可能不在黃油區域,以獲得在工作表上具有這些索引的成本與收益。

嵌套結果 - 與CTE一樣,當整個結果集可以放入內存中時,嵌套結果的效果最佳。當部分在內存中而部分在磁盤上時,它通常會執行比沒有索引的類似大小的臨時表更糟糕的表現。在5行左右的200k行中使用小數據類型和現代服務器,只要您一次只能執行一個結果集,您應該在嵌套查詢方面表現良好。再一次,這根據你的設置而變化,如果你被綁在RAM上,把它們放到臨時表中。

聯接 - 使用臨時表/嵌套查詢的另一個可能的好理由是爲了避免過大的聯接。加入過程的第一步是表格之間的完整笛卡爾連接,然後根據on和where子句進行過濾。 Join過程在所有RDMS中都進行了大量優化,所以大多數時候您並不知道幕後發生了多大的繁重工作,但是當表達到大尺寸時,這可能是一個主要的性能問題。因此,您可以從兩個表中選擇所需的數據子集,然後加入兩個更小的集合。子集和全表連接之間的黃油區域又一次取決於許多因素,因此您必須仔細查看查詢,找出適合您情況的位置。

不幸的是,如果沒有一些樣本輸入和輸出和/或執行計劃,我不能給出具體的建議,但我希望這是一些值得思考的食物。祝你好運。

0

聽起來好像你的數據集來自子查詢超過了幾千行,所以我會從方法A開始,將一些中間結果集保存到#temptables,檢查這些表上的掃描執行計劃,並根據需要爲#temptables編制索引。

如果您想要使用方法B,或者混合使用A和B,我建議在可能的情況下使用CTE而不是嵌套查詢。它們更具可讀性,並且在測試/設計查詢時更容易切換到#temptables。