【问题标题】:Does SQL have a smart JOIN algorithm?SQL 有智能 JOIN 算法吗?
【发布时间】:2015-05-11 06:58:50
【问题描述】:

假设我有三张桌子,

foo (id serial, one text, two text, three text, four text);
bar (id serial, ...)
foobar (foo_id, bar_id)

imagine foo 有四个以上的文本列和数百万行。 而 foobar 只有几个条目,只有 foo_id 等于 5

SELECT *
FROM foo f
JOIN foobar fb ON (fb.foo_id = f.id)
JOIN bar b ON (fb.bar_id = b.id)
WHERE foo_id = 5;

要优化吗? WHERE 子句会在所有表都被 JOINed 之后执行吗?还是 WHERE 会很聪明,只选择 JOIN 子句之前的行?

如果是前者..我不应该写

SELECT *
FROM (SELECT * FROM foobar WHERE foo_id=5) fb
JOIN foo f ON (fb.foo_id = f.id)
JOIN bar b ON (fb.bar_id = b.id);

?加快进程?

【问题讨论】:

  • 它将优化您的查询。你可以随时使用ANALYZE 看看会发生什么
  • 唯一可能的答案是“取决于”,它取决于很多因素。
  • 一般规则:使用 SQL,你告诉系统你想要什么,而不是如何去做optimizer 的工作是(尝试)找出产生结果的最佳方法。
  • 可能值得一读this article on "Which is faster?" questions。值得我使用您的演示模式来设置两个查询的SQL Fiddle to compare the execution plans,它们是相同的。
  • 检查执行计划。 @Adassko:你的意思是explain analyzeanalyze 本身不会显示执行计划。

标签: sql performance postgresql optimization


【解决方案1】:

优化器应该能够优化第一个查询。您可以使用ANALYZEcommand 来检查您是否获得了低成本的良好执行计划。

您需要确保有相当正确的表统计信息并且有相关的索引。我假设foo_idbar_id 是主键,所以索引应该没问题。

【讨论】:

    【解决方案2】:

    Join ordering 是任何查询优化器都会考虑的最微不足道的基本优化之一。是的,PostgreSQL 会使用它。在Controlling the Planner with Explicit JOIN Clauses阅读更多详细信息。

    您应该专注于提供适当的索引。 foobar 都需要id 上的索引,而foobar 通常需要(foo_id, bar_id) 上的索引 以及(bar_id, foo_id) 上的索引。

    按照您的建议重写查询是无操作的。子查询可能会被拉起,阅读Inside the PostgreSQL Query Optimizer

    我们尝试从 FROM 列表中提取子查询以成为连接 在父查询中

    【讨论】:

      猜你喜欢
      • 2010-09-14
      • 2011-02-28
      • 2011-02-17
      • 2010-11-22
      • 1970-01-01
      • 2015-04-17
      • 2015-12-22
      • 1970-01-01
      相关资源
      最近更新 更多