为什么mysql决定这个子查询依赖?

Bit*_*nce 3 mysql performance subquery

在MySQL 5.1.34服务器上,我有以下令人困惑的情况:

mysql> explain select * FROM master.ObjectValue WHERE id IN ( SELECT id FROM backup.ObjectValue ) AND timestamp < '2008-04-26 11:21:59';
+----+--------------------+-------------+-----------------+-------------------------------------------------------------+------------------------------------+---------+------+--------+-------------+
| id | select_type        | table       | type            | possible_keys                                               | key                                | key_len | ref  | rows   | Extra       |
+----+--------------------+-------------+-----------------+-------------------------------------------------------------+------------------------------------+---------+------+--------+-------------+
|  1 | PRIMARY            | ObjectValue | range           | IX_ObjectValue_Timestamp,IX_ObjectValue_Timestamp_EventName | IX_ObjectValue_Timestamp_EventName | 9       | NULL | 541944 | Using where | 
|  2 | DEPENDENT SUBQUERY | ObjectValue | unique_subquery | PRIMARY                                                     | PRIMARY                            | 4       | func |      1 | Using index | 
+----+--------------------+-------------+-----------------+-------------------------------------------------------------+------------------------------------+---------+------+--------+-------------+
2 rows in set (0.00 sec)

mysql> select * FROM master.ObjectValue WHERE id IN ( SELECT id FROM backup.ObjectValue ) AND timestamp < '2008-04-26 11:21:59';
Empty set (2 min 48.79 sec)

mysql> select count(*) FROM master.ObjectValue;
+----------+
| count(*) |
+----------+
| 35928440 |
+----------+
1 row in set (2 min 18.96 sec)
Run Code Online (Sandbox Code Playgroud)
  • 当只需2分钟访问所有记录时,如何检查500000条记录需要3分钟?
  • 如何将单独数据库上的子查询依赖于分类?
  • 我该怎么做才能加快这个查询?

更新:

花了很长时间的实际查询是一个DELETE,但你无法解释这些; 删除是我使用subselect的原因.我现在已阅读文档,并了解语法"DELETE FROM t USING ..."重写查询:

DELETE FROM master.ObjectValue 
WHERE timestamp < '2008-06-26 11:21:59' 
AND id IN ( SELECT id FROM backup.ObjectValue ) ;
Run Code Online (Sandbox Code Playgroud)

成:

DELETE FROM m 
USING master.ObjectValue m INNER JOIN backup.ObjectValue b ON m.id = b.id 
WHERE m.timestamp < '2008-04-26 11:21:59';
Run Code Online (Sandbox Code Playgroud)

对于空backup.ObjectValue,将时间从几分钟减少到0.01秒.

谢谢大家的好建议.

Rom*_*ain 5

依赖子查询会将外部查询减慢到爬行(我想你知道它意味着它在被查看的数据集中每行找到一次).

你不需要子查询,不使用子查询会显着加快查询速度:

SELECT m.*
FROM master.ObjectValue m
JOIN backup.ObjectValue USING (id)
WHERE m.timestamp < '2008-06-26 11:21:59'
Run Code Online (Sandbox Code Playgroud)

MySQL经常将子查询视为依赖,即使它们不是.我从来没有真正理解其确切原因 - 可能只是因为查询优化器无法将其识别为独立.我从不打扰在细节上看更多,因为在这些情况下你几乎总是可以将它移动到FROM修复它的子句.

例如:

DELETE FROM m WHERE m.rid IN (SELECT id FROM r WHERE r.xid = 10)
// vs
DELETE m FROM m WHERE m.rid IN (SELECT id FROM r WHERE r.xid = 10)
Run Code Online (Sandbox Code Playgroud)

前者将产生一个从属子查询,并且可能非常慢.后者将告诉优化器隔离子查询,这避免了表扫描并使查询运行得更快.