2010-01-06 11 views
1

首先值一張大桌子的,我知道,SQL語句從table_b更新table_a使用值是形式:性能更新使用從一個小桌子

甲骨文:

UPDATE table_a 
    SET (col1, col2) = (SELECT cola, colb 
         FROM table_b 
         WHERE table_a.key = table_b.key) 
WHERE EXISTS (SELECT * 
       FROM table_b 
       WHERE table_a.key = table_b.key) 

的MySQL :

UPDATE table_a 
INNER JOIN table_b ON table_a.key = table_b.key 
SET table_a.col1 = table_b.cola, 
    table_a.col2 = table_b.colb 

我的理解是數據庫引擎將在table_a經歷記錄和匹配與值進行更新記錄在table_b

所以,如果我有table_btable_a 1000萬點的記錄,只有10條記錄:

  1. 這是否意味着發動機將通過table_a做10個百萬只的迭代更新10條記錄? Oracle/MySQL /等足夠聰明,只需要通過table_b做10次迭代?

  2. 有沒有辦法強制引擎實際遍歷table_b中的記錄而不是table_a來執行更新?是否有一個替代語句的SQL語句?

假設table_a.keytable_b.key進行索引。

回答

3

任一引擎都應該足夠聰明,以便根據表b中只有十行的事實來優化查詢。引擎如何確定要做什麼是基於索引和統計等因素。

如果「key」列是主鍵和/或索引,引擎將不得不做很少的工作來運行此查詢。它基本上已經知道匹配行的位置,並很快查找它們。它不需要「迭代」。

如果鍵列上沒有索引,引擎將不得不進行「表掃描」(大致相當於「迭代」)以找到正確的值並匹配它們。這意味着它將不得不掃描1000萬行。

對所謂的執行計劃進行一點閱讀。這基本上解釋了引擎爲了運行查詢所做的工作(有些數據庫僅以文本顯示,有些可以選擇以圖形方式查看)。學習如何解釋執行計劃將使您深入瞭解向表中添加索引並優化查詢。

看這些,如果他們不工作(它已經有一段時間),但它是這樣的:

  • 在MySQL中,把工作「解釋」在你的SELECT語句
  • 在前面在運行你的SELECT語句之前運行「SET AUTOTRACE ON」

我認爲第一個(Oracle)查詢最好用JOIN而不是WHERE EXISTS編寫。引擎可能足夠智能,無論哪種方式都可以正確優化。一旦你解釋了一個執行計劃的竅門,你可以通過兩種方式運行並親自查看。:)

+0

實際上,IN/EXISTS在Oracle中比使用JOIN更好(給出適當的標準):http://explainextended.com/2009/09/30/in-vs- join-vs-exists-oracle/ –

+0

有趣。 HASH JOIN SEMI是一個聰明的優化。儘管只有列沒有編入索引似乎很重要。我可能仍然會使用JOIN失敗(更具表現力的恕我直言)。但對於某些情況下的知道絕對有用! –

1

好吧,我知道回答自己的問題時通常是皺起了眉頭,但我已經接受了另一個答案,也不會取消接受這麼MEH這裏是..

,我發現了一個更好的選擇,我」 d喜歡與遇到相同場景的任何人分享:MERGE聲明。

顯然,較新的Oracle版本引入了這個MERGE聲明,這個聲明簡直太棒了!不僅如此,在大多數情況下,性能更好,語法非常簡單,所以我覺得使用UPDATE聲明時感覺很愚蠢!這裏說到..

MERGE INTO table_a 
USING table_b 
ON (table_a.key = table_b.key) 
WHEN MATCHED THEN UPDATE SET 
    table_a.col1 = table_b.cola, 
    table_a.col2 = table_b.colb; 

什麼更多的是,我還可以在table_b擴展語句包括INSERT行動時,table_a沒有匹配的記錄了一段記錄:

MERGE INTO table_a 
USING table_b 
ON (table_a.key = table_b.key) 
WHEN MATCHED THEN UPDATE SET 
    table_a.col1 = table_b.cola, 
    table_a.col2 = table_b.colb 
WHEN NOT MATCHED THEN INSERT 
    (key, col1, col2) 
    VALUES (table_b.key, table_b.cola, table_b.colb); 

這個新的語句類型在我發現它的那一天做了我的一天:)

相關問題