首頁  >  問答  >  主體

MySQL update select 速度缓慢

有如下两个表,引擎都为MyISAM
a,表a中包含150W条数据

b,表b中包含50W条数据

其中表a的iplong为ip地址的long类型,如果a.iplong >= b.ip1 and a.iplong < b.ip2 表b中的该记录中的country和city填充到a中的country和city

现在写了一条语句

update a inner join (SELECT * FROM b) on a.iplong >=b.ip1 and a.iplong < b.ip2
set a.country = b.country, a.city = b.city ;

粗略估计了一下可能需要16个小时。

请问有什么办法提升速度吗?这条语句耗时在哪部分?

更新1
explain update copy_of_log a use index (primary, iplong) inner join ipdizhi b on a.iplong >=b.ip1 and a.iplong < b.ip2 set a.country = b.country, a.city = b.city

返回

没使用任何索引?是因为连接不会使用索引吗?这种功能难道使用子查询会更快吗?

黄舟黄舟2742 天前889

全部回覆(4)我來回復

  • PHP中文网

    PHP中文网2017-04-17 11:46:10

    嵌套了子查詢,任何SQL一旦嵌套了子查詢速度大大降低,我在工作中,除非一定必須用子查詢,否則我絕不會寫嵌套子查詢的,我看你(select * from b) 後面居然不加limit 限制行數?萬一要是1000萬的數據呢?

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-17 11:46:10

    可以試試先join insert到臨時表 之後用臨時表join update

    不考慮效率可以while循環更新
    http://stackoverflow.com/questions/11430362/update-column-from-another-table-in-large-mysql-db-7-million-rows

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-17 11:46:10

    這裡一定是子巢狀查詢導致速度過慢,如果有興趣可以把資料集發上來,這樣可以幫忙調一下SQL。一次取出所有表格資料那個IO開銷太高,可以試試這樣寫:
    update a set a.country = b.country, a.city = b.city from b where a.iplong >=b.ip1 and a.iplong < b.ip2;

    另外看不到你ip欄位用什麼資料型別儲存的,這種比較用int會得到比較好的效能。

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 11:46:10

    執行計畫看沒踏上索引,,iplong 踏不上索引的。能否把建表,索引語句貼出來。對於大數據量的UPDATE 因為 回滾段比較大,所以會很慢。可以透過 b表 ip1 ,ip2 加上索引
    create table a_1 as select a.id,a.ipdizhi,a.iplong,(select b.country from b where a.iplong >=b.ip1 and a.iplong < b.ip2) as country,(select b.city from b where a.iplong >=b.ip1 and a.iplong < b.ip2) as city from a;
    來實現,然後把兩張a表換下。

    回覆
    0
  • 取消回覆