基于以下查询的数据量,我的返回时间很慢。
mysql> explain select *
from worker_location
where gate_id not in (
SELECT gate_id from worker_address
);
+----+--------------------+---------------------+-------+---------------------------+---------------------------+---------+------+---------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------------------+-------+---------------------------+---------------------------+---------+------+---------+--------------------------+
| 1 | PRIMARY | worker_location | ALL | NULL | NULL | NULL | NULL | 527347 | Using where |
| 2 | DEPENDENT SUBQUERY | worker_address | index | gate_id_idx | gate_id_ix | 48 | NULL | 3041342 | Using where; Using index |
+----+--------------------+---------------------+-------+---------------------------+---------------------------+---------+------+---------+--------------------------+
2 rows in set (0.00 sec)
我试着使用左连接,但得到相同的计划,没有好处的速度。
mysql> explain select *
from worker_location wl
left join worker_address wa ON wl.gate_id=wa.gate_id
where wa.gate_id is null;
+----+-------------+-------+------+---------------+------+---------+------+---------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+---------+----------------------------------------------------+
| 1 | SIMPLE | wl | ALL | NULL | NULL | NULL | NULL | 527347 | NULL |
| 1 | SIMPLE | wa | ALL | NULL | NULL | NULL | NULL | 3041342 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+---------------+------+---------+------+---------+----------------------------------------------------+
2 rows in set (0.00 sec)
有没有办法进一步优化这个查询?
2条答案
按热度按时间ukqbszuj1#
一些分析:
您必须接触第一个表的大约527347行。
对于每一个表,它都检查另一个表。
为什么是
gate_id
这么大?48字节??第一个查询(不在中)使用索引(“using index”),因此对于527347随机查找相当有效。
第二个查询(左连接)加载整个索引。这可能比访问表527347次更有效,具体取决于缓存的内容。
第三种方法:
每个变种需要多长时间?
为进一步讨论,请提供
SHOW CREATE TABLE
对于两个表和innodb_buffer_pool_size
. 这可能导致其他优化技术。8tntrjer2#
请参见解释输出中的两个问题:
未使用索引-请参阅“可能的\u键”和“键”列
“块嵌套循环”优化触发,可能会击中一个袋子
你可以尝试使用索引提示
和/或尝试通过以下方式禁用bnl:
SET SESSION optimizer_switch='block_nested_loop=off';