我正在对数据库进行一些工作以使其更有条理。目前,每个记录都由3列组合标识 - 因此它目前有一个唯一键,由三个项u1
,u2
和u3
组成。但是,我有另一个表格将u1
,u2
和u3
与另一个唯一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。我还在两个表中的键u1
,u2
和u3
上添加了索引,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 |
+------+-------------+-----------------------+------+---------------------------+----------+---------+-----------------------------------------------+---------+-------------+
答案 0 :(得分:1)
每个表有三个索引,分别为列u1,u2和u3。这不会有太大帮助,因为任何给定的查询一次只能使用一个索引。
相反,对于每个表,您需要一个跨越构成主键或唯一键的所有列的索引:
$riderAll = Riders::find()->select(['user_id'])->asArray()->all();
$tableData = array_diff($tableData, $riderAll);