我在3个表中有15行(一个表是原始CSV导入,另两个是该CSV的规范化版本+一些其他数据)。
我只需要更新原始CSV表中的一个字段。加入这些表的更新查询现在已经在我的四核8GB-固态硬盘盒上运行了30个小时。
这正常吗?有没有更好的方法来执行这个简单的更新?

Tables: ti (the CSV dump, denormalized, ~13M rows)
        i (the primary, normalized table, ~17M rows)
        icm (a map of ti.raw_id to i.item_id, ~17M rows)

mysql> explain select * from item AS i, item_catalog_map AS icm, temp_input AS ti WHERE i.id=icm.item_id AND icm.catalog_unique_item_id=ti.productID;
+----+-------------+-------+--------+----------------------+----------------------+---------+------------+----------+-------------+
| id | select_type | table | type   | possible_keys        | key                  | key_len | ref        | rows     | Extra       |
+----+-------------+-------+--------+----------------------+----------------------+---------+------------+----------+-------------+
|  1 | SIMPLE      | i     | ALL    | PRIMARY              | NULL                 | NULL    | NULL       | 13652592 |             |
|  1 | SIMPLE      | icm   | ref    | IDX_ACD6184F126F525E | IDX_ACD6184F126F525E | 5       | frugg.i.id |        1 | Using where |
|  1 | SIMPLE      | ti    | eq_ref | PRIMARY              | PRIMARY              | 767     | func       |        1 | Using where |
+----+-------------+-------+--------+----------------------+----------------------+---------+------------+----------+-------------+
3 rows in set (0.06 sec)

mysql> UPDATE item AS i, item_catalog_map AS icm, temp_input AS ti
    -> SET i.name=ti.productName,
    ->     icm.price=ti.retailPrice,
    ->     icm.conversion_url=productURL
    -> WHERE i.id=icm.item_id AND icm.catalog_unique_item_id=ti.productID;

最佳答案

首先,如果您的非规范化数据有13M条记录,但是您的两个“规范化”表都有17M条记录,那么您的规范化不会得到太多压缩。
其次,尝试在一个SQL语句中更新两个规范化表。我认为应该先更新映射表,然后在第二个SQL语句中更新数据表。
第三,执行内部连接可以加快速度,因为查询正在执行三向笛卡尔积。好吧,不完全是,因为您只是在做join old school,优化器应该接受它,但同样地,使用join语法。

UPDATE item_catalog_map AS icm
       INNER JOiN temp_input AS ti
          ON icm.catalog_unique_item_id = ti.productID
  SET icm.price = ti.retailPrice,
      icm.conversion_url = productURL;


UPDATE item AS i
       INNER JOIN temp_input AS ti
          ON i.id = icm.item_id
  SET i.name = ti.productName;

最后,要确定的索引是:
CREATE INDEX IDX_CATALOG ON item_catalog_map (catalog_unique_item_id);
CREATE INDEX IDX_RAW_PRODUCT_ID ON temp_input (productID);
CREATE INDEX IDX_RAW_ITEM_ID ON temp_input (item_id);

关于mysql - MySQL:连接3个表的UPDATE查询运行时间长(1500万行表,已建立索引),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12799419/

10-17 03:09