Rea*_*lar 3 mysql database-performance
鉴于MySQL中的这个SQL查询:
SELECT * FROM tableA WHERE tableA.id IN (SELECT id FROM tableB);
Run Code Online (Sandbox Code Playgroud)
MySQL是否SELECT id FROM tableB为每一行执行多次子查询tableA?
有没有办法让sql更快,而不使用变量或存储过程?
为什么这通常比使用慢LEFT JOIN?
你的假设是假的; 子查询只执行一次.它比连接慢的原因是因为IN无法利用索引; 每次WHERE计算子句时,它必须扫描一次参数,即tableA中每行一次.您可以在不使用变量或存储过程的情况下优化查询,只需将其替换IN为连接,即:
SELECT tableA.field1, tableA.field2, [...]
FROM tableA
INNER JOIN tableB ON tableA.id = tableB.id
Run Code Online (Sandbox Code Playgroud)
除非你不介意从两个表中取回每个字段,否则你需要在SELECT子句中枚举你想要的字段; tableA.*例如,将引发语法错误.
首先,这取决于 MySQL 的版本。我相信 5.6 版可以正确优化此类查询。MySQL 文档对此不一致。例如,这里说了一件事:
考虑以下子查询比较:
outer_expr IN (SELECT inner_expr FROM ... WHERE subquery_where)
Run Code Online (Sandbox Code Playgroud)
MySQL“从外到内”评估查询。也就是说,它首先获取外部表达式outer_expr 的值,然后运行子查询并捕获它产生的行。
这种“从外到内”意味着对每一行评估子查询。这与我使用 MySQL 的经验一致。
文档在这里另有建议:
MySQL 本身所做的一些优化是:
- MySQL 只执行一次不相关的子查询。使用 EXPLAIN 来确保给定的子查询确实是不相关的。
- MySQL 重写 IN、ALL、ANY 和 SOME 子查询以试图利用子查询中的选择列表列被索引的可能性。
我相信,语句也不会参考in条款。可能发生的情况是将子查询重写为相关子查询以检查索引,然后多次运行(无论是否存在索引)。
| 归档时间: |
|
| 查看次数: |
3139 次 |
| 最近记录: |