2010-03-03 117 views
2

我有一個更新語句去這樣的:Update語句

update tableA 
    set val1='X', val2='Y' 

where id in (
    select id from tableA A 

    LEFT JOIN tableB B ON A.col1=B.col1 and A.col2=B.col2 

    where A.col3='xx' and B.col3= 'YY') 

現在,內SELECT語句在10分鐘內返回1000條記錄運行(包括表A和tableB的有關於10MIL記錄每個)

整個更新語句運行3小時(尚未等待完成)

任何想法?

+0

它可能爲tableA中的每一行運行內部查詢。你使用的是哪個數據庫? – 2010-03-03 16:18:41

+0

數據庫是DB2 – Peter 2010-03-03 16:23:00

+0

表A上是否有涉及修改列的索引?開銷可能會減慢進程 – 2010-03-03 16:24:41

回答

2

tableA.id上可能沒有索引,或者tableA.id的類型與select返回的類型不匹配。

[編輯]或者,你可以試試這個奇怪的語法:

update (
    select val1, val2 from tableA A 

    LEFT JOIN tableB B ON A.col1=B.col1 and A.col2=B.col2 

    where A.col3='xx' and B.col3= 'YY' 
) tmp 
set val1='X', val2='Y' 

這將創建仍鏈接到原始表的臨時表,所以你可以更新其數值的選擇回報,他們將出現在原始表格中。

[EDIT2]我錯過了選擇和更新同一個表的事實(即id是同一列)。在這種情況下,類型顯然並不重要,你甚至不需要索引(因爲select已經返回正確的行)。

嘗試EXPLAIN PLAN看看是否有其他事情正在發生。

此外,您可能在與另一個進程,這也更新了同桌衝突得到(即你有地方的鎖)。 AQT有一個顯示器可以顯示這些東西。如果可以的話,獲得AQT並使用它。它對DB2有着出色的支持,比迄今爲止我看到的更好。

+1

這是同一張桌子上的同一列...不知道它如何與類型不匹配... – 2010-03-03 16:19:59

+1

+1 - 良好的通話。另外,您可以嘗試對查詢進行EXPLAIN。 – 2010-03-03 16:20:27

+1

tableA.id上有一個索引 我不認爲tableA.id問題的類型在這裏是有效的。 – Peter 2010-03-03 16:20:49

0

我已經在過去的成功與突破的子查詢出來,並存儲其輸出到一個臨時表。例如

CREATE TEMPORARY TABLE my_ids (id INT); 

INSERT INTO my_ids select id from tableA A 

    LEFT JOIN tableB B ON A.col1=B.col1 and A.col2=B.col2 

    where A.col3='xx' and B.col3= 'YY'; 

update tableA 
    set val1='X', val2='Y' 
WHERE id IN (SELECT id FROM my_ids); 

如果特定的SQL味道已經某種更新JOIN式的語法(如UPDATE TABLEA使用my_ids)也可能是值得嘗試

+0

這確實是一個解決方案,但這是一個日常的批處理作業,DBA對於創建這些臨時表並不酷。 – Peter 2010-03-03 16:24:07

+0

您可以使用全局臨時表,這些臨時表只有在聲明它們的應用程序結束其與數據庫的連接之後才存在。 – 2010-03-04 00:20:56

0

你有任何的列的索引?如果您在tableA.col1,tableB.col1,tableA.col2,tableB.col2,tableA.col3和tableB.col3上沒有索引,則可以解釋長查找時間。如果你沒有這些比較的索引,你將被迫掃描整個表,這將是緩慢的。

而且,即使你有,你應該檢查,看看你的統計數據是最新的指標;如果它們不是,那麼即使索引的物理結構很好,也會導致問題。

你沒有提到你正在使用的數據庫,但是如果你有辦法讓它告訴你查詢的執行計劃,你可以使用它來確定它正在做什麼並採取適當的行動來添加您需要的索引。

0

您應該嘗試更新連接,因爲這應該會改進解釋計劃。

update tableA A, tableB B 
set A.val1='X', A.val2='Y' 
where A.col1 = B.col1 and A.col2 = B.col2 
    and A.col3 = 'xx' and B.col3 = 'YY' 

其他人已經說過,索引顯然會對這個連接有所幫助。如果您希望我們檢查索引是否正在使用,請複製EXPLAIN結果。

+0

DB2中不支持此語法。 – 2010-03-04 00:19:44

+0

我寫這個時沒有指定DB2。 – 2010-03-04 07:25:35

0

其他人建議使用EXPLAIN來幫助識別查詢速度慢的地方,這當然是一個好主意。

另外一個建議,雖然uou不要說你正在使用的DB2版本,或者是什麼平臺,它是:

您可能需要使用MERGE語句,這是ANSI SQL語句來嘗試的更新加入(這已在自V8.2 DB2用於Linux/UNIX/Windows的是可利用):

MERGE語句看起來是這樣的(未測試):

merge into tableA a 
    using (select id, col1, col2 from tableB where col3 = 'YY') as b 
    on (a.col1 = b.col1 and a.col2 = b.col2 and a.col3 = 'xx') 
    when matched 
    then update set val1 = 'X', val2 = 'Y' 
2

我知道這個線程有點老,但我喜歡分享發生在我身上的事情(具體的今天盟友今天呵呵)。

我們正面臨同樣的問題。更新永遠在運行! 所以我們發現我們試圖更新的表被鎖定了。但是,DB2沒有引發錯誤消息。

希望Ive幫助過某種程度! 歡呼聲。 〜chamb〜