哪一个更快
select * from parents p
inner join children c on p.id = c.pid
where p.x = 2
OR
select * from
(select * from parents where p.x = 2)
p
inner join children c on p.id = c.pid
where p.x = 2
答案 0 :(得分:6)
在MySQL
中,第一个更快:
SELECT *
FROM parents p
INNER JOIN
children c
ON c.pid = p.id
WHERE p.x = 2
,因为使用内联视图意味着生成并传递记录两次。
在其他引擎中,它们通常被优化为使用一个执行计划。
MySQL
在并行化和流水线化结果流方面不是很好。
喜欢这个查询:
SELECT *
FROM mytable
LIMIT 1
是即时的,而这一个(在语义上是相同的):
SELECT *
FROM (
SELECT *
FROM mytable
)
LIMIT 1
将首先从mytable
中选择所有值,在某处缓冲它们,然后获取第一条记录。
对于Oracle
,SQL Server
和PostgreSQL
,上述查询(以及您的两个查询)很可能会产生相同的执行计划。
答案 1 :(得分:4)
我知道这是一个简单的案例,但你的第一个选择比第二个选项更具可读性。只要两个查询计划具有可比性,我就会选择更易于维护的SQL代码,这是我的第一个例子。
答案 2 :(得分:2)
这取决于数据库在优化查询方面的优势。
如果数据库设法将第二个优化为第一个,它们同样快,否则第一个更快。
第一个为数据库提供了更多自由来优化查询。第二个建议具体的做事顺序。数据库能够看到过去并将其优化为单个查询,或者它将查询作为两个单独的查询运行,子查询作为中间结果。
像SQL Server这样的数据库会保存有关数据库表包含内容的统计信息,它用于确定如何以最有效的方式执行查询。例如,根据将消除大多数记录的内容,它可以从加入表开始,也可以在条件上过滤parents
表。如果您编写的查询强制执行特定订单,则可能不是最有效的订单。
答案 3 :(得分:0)
我认为第一个。我不确定优化器是否会在第二个查询中使用派生表上的任何索引,或者它是否会在连接回子节点之前复制匹配到内存中的所有行。
答案 4 :(得分:0)
这就是你有DBA的原因。它完全取决于DBMS,以及如何配置表和索引,以及哪一个运行速度最快。
数据库调优不是一种“一劳永逸”的操作,应该在数据发生变化时定期进行,以确保数据库以最佳性能运行。如果没有指定,问题就没那么有意义了:
您应该通过查询优化器运行这两个查询,以查看哪一个最快,然后开始使用该查询。这首先假设差异明显。如果差异很小,那么最容易阅读/维护。
答案 5 :(得分:0)
对我来说,在你说的第二个查询中,我不相信优化器会优化这个查询,所以我会提供一些“提示”。
我会说,相信优化器,直到它让你失望,然后才考虑尝试为它做优化工作。