2011-04-01 28 views
2

嘿,我有以下表和SQL:的Sybase專家的幫助:GROUPBY聚合性能問題

T1:ID,COL2,COL3 - PK(ID) - 23mil行

T2:ID,COL2,COL3 - PK(ID) - 23mil行

T3:ID,名稱,值 - PK(ID,姓名)-66mil行

1)以下SQL返回的10K行結果集非常快,沒有任何問題。

select top 10000 T1.col2, T2.col2, T3.name, T4.value 
from T1, T2, T3 
where T1.ID = T2.ID and T1.ID *= T3.ID and T3.name in ('ABC','XYZ') 
and T2.col1 = 'SOMEVALUE' 

2)下面的SQL佔用了FOREVER。

select top 10000 T1.col2, T2.col2, 

ABC = min(case when T3.name='ABC ' then T3.value end) 
XYZ = min(case when T3.name='XYZ ' then T3.value end) 

from T1, T2, T3 

where T1.ID = T2.ID and T1.ID *= T3.ID and T3.name in ('ABC','XYZ') 
and T2.col1 = 'SOMEVALUE' 

group by T1.col2, T2.col2, 

這兩個查詢之間的showplan唯一區別在於查詢2)。我不明白它的100%,是不是選擇ENTIRE結果集沒有頂10000進入臨時表,然後做一個組?這就是爲什麼它很慢?

STEP 1 
    The type of query is SELECT (into Worktable1). 
    GROUP BY 
    Evaluate Grouped MINIMUM AGGREGATE. 

    FROM TABLE ...etc.. 

    TO TABLE 
     Worktable1. 

STEP 2 
    The type of query is SELECT. 

    FROM TABLE 
     Worktable1. 
    Nested iteration. 
    Table Scan. 
    Forward scan. 
    Positioning at start of table. 
    Using I/O Size 16 Kbytes for data pages. 
    With MRU Buffer Replacement Strategy for data pages. 

我的問題是

1)爲什麼查詢2)這麼慢

2)如何解決,同時保持查詢邏輯相同,最好限制它只是1像以前一樣選擇SQL。

謝謝

回答

1

雖然可能是一個通用的答案,我會說把一個指標上你的分組由列。

編輯/修訂:這是我重新審視這個問題後的理論。查詢中的SELECT語句始終是執行的最後一行。這是有道理的,因爲它是從下面指定的數據集中檢索所需值的語句。在您的查詢中,將針對您指定的MIN值表達式計算整個數據集(數百萬條記錄)。由於在select語句中指定了兩個MIN列,因此將在整個數據集上調用兩個獨立的函數。 之後,對數據集進行過濾,並確定MIN列,然後選擇頂部10000行。

簡而言之,你要對數百萬條記錄做兩個數學函數。這將花費大量時間,特別是在沒有索引的情況下。

您的解決方案將使用派生表。我沒有編譯下面的代碼,但它接近你將使用的東西。它只會取得10,000條記錄的最小值而不是整個數據集。

I.e.

Select my_derived_table.t1col2, my_derived_table.t2col2, 
    ABC = min(case when my_derived_table.t3name ='ABC ' then my_derived_table.t3value end), 
    XYZ = min(case when my_derived_table.t3name='XYZ ' then my_derived_table.t3value end) 
    FROM 
     (Select top 10000 T1.col2 as t1col2, 
       T2.col2 as t2col2, 
       t3.name as t3name, 
       t3.value as t3.value 
     from T1, T2, T3 
     where T1.ID = T2.ID 
     and T1.ID *= T3.ID 
     and T3.name in ('ABC','XYZ') 
     and T2.col1 = 'SOMEVALUE') my_derived_table 
group by my_derived_table.t1col2, my_derived_table.t2col2 
+0

我不能,它都是動態生成的,我們有200多個表格,每個表格有50多列。用戶可以選擇任何表格,他們想要的任何列,這些是我們使用的分組。我想更多地瞭解爲什麼這個小組造成性能問題。它在內部做什麼是瓶頸。謝謝 – user688218 2011-04-01 20:30:35

+0

我更新了我的答案,希望這有助於解釋原因。 – contactmatt 2011-04-08 20:47:10