我想知道 INNER JOIN 或 INNER SELECT 哪个更快?
select t1.* from test1 t1
inner join test2 t2 on t1.id = t2.id
where t2.id = 'blah'
或者
select t1.* from test1 t1
where t1.id IN (select t2.id from test2 t2 where t2.id = 'blah')
假设id
是关键,这些查询意味着同样的事情,一个体面的 DBMS 将以完全相同的方式执行它们。不幸的是 MySQL 没有,正如在这个SQL Fiddle中展开“查看执行计划”链接可以看出的那样。哪个更快可能取决于表的大小 - 如果TABLE1
行数很少,那么 IN 有可能更快,而 JOIN 在所有其他情况下可能会更快。
这是 MySQL 查询优化器的一个特性。我从未见过Oracle、PostgreSQL或MS SQL Server以不同的方式执行如此简单的等效查询。
如果您必须猜测,INNER JOIN
它可能比 更有效IN (SELECT ...)
,但这可能因一个查询而异。
EXPLAIN
关键字是您最好的朋友之一。EXPLAIN
在您的完整查询前面键入, SELECT
MySQL 将为您提供一些有关它将如何执行查询的基本信息。它会告诉你它在哪里使用文件排序,它在哪里使用你创建的索引(以及它在哪里忽略它们),以及它可能需要检查多少行才能满足请求。
如果其他一切都相同,请使用INNER JOIN
主要是因为它更容易预测,因此对新开发人员来说更容易理解。当然,如果您看到IN (SELECT ...)
表单的真正优势,请使用它!
尽管您必须检查您要查询的任何 RDBS 的执行计划,但我想这inner join
会更快或至少相同。如果我错了,也许有人会纠正我。
无论如何,嵌套选择很可能会运行整个内部查询,并从test2
. 如果该查询返回一百万行,那么无论如何您都已经承担了将该数据加载到内存中的成本。
使用内部连接,如果test1
只有 2 行,它可能只会对每行test2
的id
值进行 2 次索引扫描,而不必将一百万行加载到内存中。
更现代的数据库系统也有可能优化第一个场景,因为它对每个表都有统计信息,但是在最好的情况下,内部连接是相同的。
在大多数情况下,JOIN 比子查询快得多,但子查询比 JOIN 更具可读性。
RDBMS 针对 JOIN 创建一个执行计划,因此可以预测应该加载哪些数据以进行处理。这绝对可以节省时间。另一方面,对于子查询,它运行所有查询并加载所有数据以进行处理。