我在3个表中有15M行(一个表是原始CSV导入,另外两个是该CSV的标准化版本+其他一些数据)。
我只需要从原始CSV表中更新一个字段。加入这些表的更新查询现在在我的四核-8GB-ssd盒子上运行了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;
答案 0 :(得分:1)
首先,如果你的非规范化数据有13M记录,但你的“规范化”表中的都有17M记录,那么你的规范化就不会得到很多压缩。
其次,您尝试在一个SQL语句中更新两个规范化表。我认为您应该首先更新映射表,然后在第二个SQL语句中更新数据表。
第三,进行内部联接可以加快速度,因为您的查询正在执行三向笛卡尔积。嗯,不完全是,因为你只是在加入旧学校,优化器应该选择它,但不过,使用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);