-1

我有兩個表:token_type,CUST_ID(小學) 2. 200K數據 列pm_tmp表: 有大約1000萬的數據 列1.用戶表ID(主|自動增加),user_id說明Mysql性能:哪個查詢需要更多時間?

USER_ID是CUST_ID外鍵

1接近角/查詢:

update user set token_type='PRIME' 
where cust_id in (select user_id from pm_tmp where id between 1 AND 60000); 

第二接近角/查詢:在這裏我們將運行下面的查詢針對不同的cust_id單獨爲60000個記錄:

update user set token_type='PRIME' where cust_id='1111110'; 
+3

當你測量它時,你得到了什麼結果? –

+0

第二種方法花費的時間更少。但我試圖找出原因。 –

+0

這是因爲,第一個查詢將需要爲您的innodb緩衝池配置足夠的內存以使其快速執行。第二個是單事務查詢將需要相對較少的時間。 – Nans

回答

0

對於第一個查詢,理論上時間會少一些,因爲它涉及的提交數量較少,而索引重建次數較少。但是,我會建議採用第二種方法,因爲它的控制更好,並且時間會更少,您可以事先考慮執行2個單獨的套件。

注意:第一個查詢將需要足夠的內存供應給mysql緩衝區以快速執行。第二個查詢是獨立的單個事務查詢的集合,它們將需要相對較少的內存,因此如果在有限的內存環境中執行,則會顯得更快。

那麼,你也可以用這種方式重寫第一個查詢。

update user u, pm_tmp p set u.token_type='PRIME' where u.cust_id=p.id and p.in <60000;

0

MySQL的一些版本的麻煩優化in。我建議:

update user u join 
     pm_tmp pt 
     on u.cust_id = pt.user_id and pt.id between 1 AND 60000 
    set u.token_type = 'PRIME' ; 

(注:這假定cust_idpm_temp重複。如果這是可能的,你會希望有一個select distinct子查詢。)

你的第二個版本通常會相當慢,因爲它需要執行數千個查詢而不是一個查詢。一個考慮可能是update。隨着更新數量的增加,日誌記錄和鎖定可能會變得更加複雜。我實際上對MySQL內部知道的知之甚少,不知道這是否會對性能產生重大影響。

0

IN (SELECT ...)很差優化。 (我無法提供具體細節,因爲UPDATEIN在某些最新版本的MySQL中已經得到了更好的優化。)只要說「避免IN (SELECT ...)」即可。

你的第一句話應該說「行」而不是「列」。

回到問題的其餘部分。 60K太大了。我建議只有1000.除此之外,戈登的答案可能是最好的。

但是...您沒有使用OFFSET;做不是被誘惑使用它;當你越走越遠時,它會導致性能下降。

另一件事。每塊後面有COMMIT。否則你建立一個巨大的撤銷日誌;這增加了成本。 (這也是1K可能比60K更快的原因。)

但是等一下!你爲什麼要更新一個巨大的桌子?那就是通常是這是壞模式設計的標誌。請解釋數據流。

也許你計算了哪些項目標記爲'素數'?那麼,你可以保留這個清單,並在SELECTs中做JOINs以發現閱讀時的主要性。這完全消除了UPDATE的問題。當然,JOIN的成本,但不是很多。