更有效地执行连接和更新

时间:2015-12-17 18:23:33

标签: mysql

我正在对数据库进行一些工作以使其更有条理。目前,每个记录都由3列组合标识 - 因此它目前有一个唯一键,由三个项u1u2u3组成。但是,我有另一个表格将u1u2u3与另一个唯一ID uid相关联。具有三重唯一标识符的表具有月值,而具有单个唯一标识符的表仅是信息列。我想从信息表中取出uid并将其放在月表中。所以我在月度表中创建了一个uid列并写了这个查询。

解释输出如下:

UPDATE monthly_table
INNER JOIN information_table ON
monthly_table.u1 = information_table.u1 AND monthly_table.u2 = information_table.u2
AND monthly_table.u3 = information_table.u3
SET monthly_table.uid = information_table.uid;

不幸的是,我在每月表中有大约800万行,当我运行此查询(从命令行)时,它需要大约1小时才能完成。我已将InnoDB缓存设置为3或4GB。我还在两个表中的键u1u2u3上添加了索引,EXPLAIN表示将使用这些键进行2次简单选择。

有没有办法让这个查询更有效率,以便更快?我不经常这样做,但我想知道我需要再次这样做,以便更好地理解mySQL。

+------+-------------+-----------------------+------+---------------------------+----------+---------+-----------------------------------------------+---------+-------------+
| id   | select_type | table                 | type | possible_keys             | key      | key_len | ref                                           | rows    | Extra       |
+------+-------------+-----------------------+------+---------------------------+----------+---------+-----------------------------------------------+---------+-------------+
|    1 | SIMPLE      | monthly_table         | ALL  | u1,u2,u3                  | NULL     | NULL    | NULL                                          | 8284393 | Using where |
|    1 | SIMPLE      | information_table     | ref  | u2,u1,u3                  | u3       | 33      |dbname.monthly_table.u1                        |       2 | Using where |
+------+-------------+-----------------------+------+---------------------------+----------+---------+-----------------------------------------------+---------+-------------+

1 个答案:

答案 0 :(得分:1)

每个表有三个索引,分别为列u1,u2和u3。这不会有太大帮助,因为任何给定的查询一次只能使用一个索引。

相反,对于每个表,您需要一个跨越构成主键或唯一键的所有列的索引:

$riderAll = Riders::find()->select(['user_id'])->asArray()->all();
 $tableData = array_diff($tableData, $riderAll);