2013-05-01 178 views
0

以下通過SQL Server Management Studio執行的查詢非常緩慢。SQL Server查詢運行速度非常慢

輸入表tbl_sb12_bhs約有40000條記錄,一小時後只處理40條記錄。

在這裏可以改變什麼使其運行速度更快?

DECLARE @bsrange INT 

SET @bsrange = 0 

WHILE @bsrange <= (SELECT max([p_a_l_out]) 
        FROM [DB001].[FD\f7].[tbl_sb12_bhs]) 
    BEGIN 
     INSERT INTO [FD\f7].tbl_sb13_b_lin1 
        (aId, 
        p_a_l_out, 
        bs_id, 
        bs_db, 
        bs_tbl, 
        bs_column, 
        Int1, 
        cd1, 
        Hop1, 
        Int2, 
        cd2, 
        Hop2, 
        Int3, 
        cd3, 
        Hop3, 
        Int4, 
        cd4, 
        Hop4, 
        Int5, 
        cd5, 
        Hop5, 
        Int6, 
        cd6, 
        Hop6, 
        Int7, 
        cd7, 
        Hop7, 
        Int8, 
        cd8, 
        Hop8, 
        Int9, 
        cd9, 
        Hop9, 
        Int10, 
        cd10, 
        Hop10, 
        Int11, 
        cd11, 
        Hop11, 
        Int12, 
        cd12, 
        Hop12, 
        Int13, 
        cd13, 
        Hop13, 
        Int14, 
        cd14, 
        Hop14, 
        Int15, 
        cd15, 
        Hop15, 
        Int16, 
        cd16, 
        Hop16) 
     SELECT DISTINCT tbl_sb12_bhs.aId, 
         tbl_sb12_bhs.p_a_l_out, 
         tbl_sb12_bhs.bs_id, 
         tbl_sb12_bhs.bs_db, 
         tbl_sb12_bhs.bs_tbl, 
         tbl_sb12_bhs.bs_column, 
         tbl_rpt_val_pt_crl.pt_el_Int AS Int1, 
         tbl_rpt_val_pt_crl.user_cd  AS cd1, 
         tbl_rpt_val_pt_crl.cfk_upel  AS Hop1, 
         tbl_rpt_val_pt_crl_1.pt_el_Int AS Int2, 
         tbl_rpt_val_pt_crl_1.user_cd AS cd2, 
         tbl_rpt_val_pt_crl_1.cfk_upel AS Hop2, 
         tbl_rpt_val_pt_crl_2.pt_el_Int AS Int3, 
         tbl_rpt_val_pt_crl_2.user_cd AS cd3, 
         tbl_rpt_val_pt_crl_2.cfk_upel AS Hop3, 
         tbl_rpt_val_pt_crl_3.pt_el_Int AS Int4, 
         tbl_rpt_val_pt_crl_3.user_cd AS cd4, 
         tbl_rpt_val_pt_crl_3.cfk_upel AS Hop4, 
         tbl_rpt_val_pt_crl_4.pt_el_Int AS Int5, 
         tbl_rpt_val_pt_crl_4.user_cd AS cd5, 
         tbl_rpt_val_pt_crl_4.cfk_upel AS Hop5, 
         tbl_rpt_val_pt_crl_5.pt_el_Int AS Int6, 
         tbl_rpt_val_pt_crl_5.user_cd AS cd6, 
         tbl_rpt_val_pt_crl_5.cfk_upel AS Hop6, 
         tbl_rpt_val_pt_crl_6.pt_el_Int AS Int7, 
         tbl_rpt_val_pt_crl_6.user_cd AS cd7, 
         tbl_rpt_val_pt_crl_6.cfk_upel AS Hop7, 
         tbl_rpt_val_pt_crl_7.pt_el_Int AS Int8, 
         tbl_rpt_val_pt_crl_7.user_cd AS cd8, 
         tbl_rpt_val_pt_crl_7.cfk_upel AS Hop8, 
         tbl_rpt_val_pt_crl_8.pt_el_Int AS Int9, 
         tbl_rpt_val_pt_crl_8.user_cd AS cd9, 
         tbl_rpt_val_pt_crl_8.cfk_upel AS Hop9, 
         tbl_rpt_val_pt_crl_9.pt_el_Int AS Int10, 
         tbl_rpt_val_pt_crl_9.user_cd AS cd10, 
         tbl_rpt_val_pt_crl_9.cfk_upel AS Hop10, 
         tbl_rpt_val_pt_crl_10.pt_el_Int AS Int11, 
         tbl_rpt_val_pt_crl_10.user_cd AS cd11, 
         tbl_rpt_val_pt_crl_10.cfk_upel AS Hop11, 
         tbl_rpt_val_pt_crl_11.pt_el_Int AS Int12, 
         tbl_rpt_val_pt_crl_11.user_cd AS cd12, 
         tbl_rpt_val_pt_crl_11.cfk_upel AS Hop12, 
         tbl_rpt_val_pt_crl_12.pt_el_Int AS Int13, 
         tbl_rpt_val_pt_crl_12.user_cd AS cd13, 
         tbl_rpt_val_pt_crl_12.cfk_upel AS Hop13, 
         tbl_rpt_val_pt_crl_13.pt_el_Int AS Int14, 
         tbl_rpt_val_pt_crl_13.user_cd AS cd14, 
         tbl_rpt_val_pt_crl_13.cfk_upel AS Hop14, 
         tbl_rpt_val_pt_crl_14.pt_el_Int AS Int15, 
         tbl_rpt_val_pt_crl_14.user_cd AS cd15, 
         tbl_rpt_val_pt_crl_14.cfk_upel AS Hop15, 
         tbl_rpt_val_pt_crl_15.pt_el_Int AS Int16, 
         tbl_rpt_val_pt_crl_15.user_cd AS cd16, 
         tbl_rpt_val_pt_crl_15.cfk_upel AS Hop16 
     FROM (SELECT DISTINCT pk_a AS aId, 
           p_a_l_out, 
           bs_id, 
           bs_db, 
           bs_tbl, 
           bs_column, 
           hop_pt_id_1, 
           hop_pt_id_2, 
           hop_pt_id_3, 
           hop_pt_id_4, 
           hop_pt_id_5, 
           hop_pt_id_6, 
           hop_pt_id_7, 
           hop_pt_id_8, 
           hop_pt_id_9, 
           hop_pt_id_10, 
           hop_pt_id_11, 
           hop_pt_id_12, 
           hop_pt_id_13, 
           hop_pt_id_14, 
           hop_pt_id_15, 
           hop_pt_id_16 
       FROM [FD\f7].tbl_sb12_bhs 
       WHERE [p_a_l_out] >= @bsrange 
        AND [p_a_l_out] < (@bsrange + 1)) AS tbl_sb12_bhs 
      LEFT JOIN tbl_rpt_val_pt_crl 
       ON tbl_sb12_bhs.hop_pt_id_1 = tbl_rpt_val_pt_crl.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_1 
       ON tbl_sb12_bhs.hop_pt_id_2 = tbl_rpt_val_pt_crl_1.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_2 
       ON tbl_sb12_bhs.hop_pt_id_3 = tbl_rpt_val_pt_crl_2.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_3 
       ON tbl_sb12_bhs.hop_pt_id_4 = tbl_rpt_val_pt_crl_3.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_4 
       ON tbl_sb12_bhs.hop_pt_id_5 = tbl_rpt_val_pt_crl_4.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_5 
       ON tbl_sb12_bhs.hop_pt_id_6 = tbl_rpt_val_pt_crl_5.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_6 
       ON tbl_sb12_bhs.hop_pt_id_7 = tbl_rpt_val_pt_crl_6.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_7 
       ON tbl_sb12_bhs.hop_pt_id_8 = tbl_rpt_val_pt_crl_7.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_8 
       ON tbl_sb12_bhs.hop_pt_id_9 = tbl_rpt_val_pt_crl_8.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_9 
       ON tbl_sb12_bhs.hop_pt_id_10 = tbl_rpt_val_pt_crl_9.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_10 
       ON tbl_sb12_bhs.hop_pt_id_11 = tbl_rpt_val_pt_crl_10.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_11 
       ON tbl_sb12_bhs.hop_pt_id_12 = tbl_rpt_val_pt_crl_11.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_12 
       ON tbl_sb12_bhs.hop_pt_id_13 = tbl_rpt_val_pt_crl_12.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_13 
       ON tbl_sb12_bhs.hop_pt_id_14 = tbl_rpt_val_pt_crl_13.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_14 
       ON tbl_sb12_bhs.hop_pt_id_15 = tbl_rpt_val_pt_crl_14.sk_el_pt 
      LEFT JOIN tbl_rpt_val_pt_crl AS tbl_rpt_val_pt_crl_15 
       ON tbl_sb12_bhs.hop_pt_id_16 = tbl_rpt_val_pt_crl_15.sk_el_pt 

     SET @bsrange = @bsrange + 1 
    END 
+3

規範化表有16行每實體上tbl_rpt_val_pt_crl參加一次,而不是16列上tbl_rpt_val_pt_crl加入了16倍。 – HardCode 2013-05-01 19:19:02

+2

想想如何在沒有循環的情況下運行單個插入quey。 – 2013-05-01 19:34:19

+0

你可以(嘗試)將結果扔到#temp表中......然後插入? – granadaCoder 2013-05-01 19:34:36

回答

0

我最好的猜測是它速度很慢,因爲你一次做一些密集的操作。沒有任何樣本數據很難,但我可以嘗試提出一些建議。

從你所說的只有一小時後才能處理40條記錄,這是循環內部正在發生的事情,正在減慢你的速度。

SELECT DISTINCT並不便宜,因爲它必須比較所有數據,並且您還比較了很多列。如果可以的話,如果將列數限制爲明確選擇所需的最小值,然後將其自動加入到原始表中,則運行速度可能會更快。它應該足夠簡單,以便對其餘部分進行單獨測試,以確保獲得相同的結果以及是否更快。

此外,您擁有的聯接越多,性能越差越好......我們爲標準化付出的代價。

無論如何,我會退一步嘗試將其分解成最小的工作單元,然後您可以單獨測試每個單元,直到找到罪魁禍首。這樣做,你可能會想到一個更好的方法來做到這一點。再次,沒有任何樣本數據,這對我來說很難幫助。

0

那麼,如果你有一個或多個目標索引,那麼SQL將重新索引每一行。我會禁用目標表上的任何索引,然後在插入完成時將它們重新命名。 Id批處理插入inro範圍(說)5k記錄,所以任何阻塞將減少,或者我會創建一個臨時文件作爲select和bcp結果中的結果。因爲每次在插入一條記錄之前,你都要做這個可怕的左連接。 SQL只能優化大約7或8個左右連接。我的猜測是,表中插入的索引很少或沒有索引,從這意味着每個聯接的表掃描或對插入的每個行的大約17個表掃描。對不起,但這種方法在每個階段都是錯誤的。或者你可以讓你的老闆給你買一個datecentre ....

0

您可能想要做的另一件事是最初將連接加入臨時表中,然後引用該連接。你不必每次都做獨特或加入。只需添加bsrange的where子句即可。

因此,這將是這樣的:

Create temporary table with as much of the joins/distinct as you can. 
while..... 
    insert into [FD\f7].tbl_sb13_b_lin1 
     select * from temptable where [p_a_l_out] >= @bsrange 
        AND [p_a_l_out] < (@bsrange + 1)