【问题标题】:When is better Multiple Queries instead of Multiple Joins?什么时候多查询而不是多连接更好?
【发布时间】:2012-01-15 01:32:08
【问题描述】:

SO中有很多类似的“多查询vs单查询”类型的问题。
但是我没有看到任何一般结论,因此我仍然对此感到困惑。

所以,我换个说法:

什么时候运行多个查询而不是多个连接的单个查询更好?

我不是在问微不足道的情况,显然加入两个或 3 个表比执行 3 个查询要快得多。

我考虑的情况是,例如您有 10 多个连接,其中一些连接是多对多关系,因此您的最终查询有 GROUP_CONCAT、LEFT 和 INNER 连接的混合等。

例如,您想要 product 名称,还想要它们的所有 图像,以及它们的所有 标签,以及它们的所有 视频,以及您可以购买的所有方向。
最好使用复杂的连接和 group_concat 进行非常长的查询(如果您不能使用 distinct,这很多时候真的很难管理),或者执行产品详细信息查询、图像查询、另一个查询标签等?

如果有助于澄清问题,我可以写一个特定的示例。但我希望这种情况的一般规则。
限制在哪里?何时使用 Joins 的单个查询比多个查询更糟糕?

而且,在这些情况下,何时运行多个 SELECT 查询更好:
在事务中运行它们更快(自动提交 = false)?
更快将多个选择合并到具有多个子选择的单个查询中?

谢谢!

【问题讨论】:

标签: sql performance select join


【解决方案1】:

极限在哪里?何时使用 Joins 的单个查询比多个查询更糟糕?

我认为划定界限并不容易,这在很大程度上取决于您的场景和情况。可能有多种因素,如索引、分区、连接列、行数、查询结构等

多个连接,例如连接 5 列,其中连接列是键,大多数行的值不同(例如性别)并且具有适当的索引可能比仅连接两个没有适当索引的表的查询更快。

我猜你可能会为自己设置限制,例如,您可以决定这个特定用例(例如插入或选择)的时间不得超过 1 秒,如果时间超过 1 秒,则可能需要更多优化。

【讨论】:

  • 是的,但我在考虑好的查询,我的意思是对于好的索引等,在性别列中使用索引是不好的,我们的连接应该总是使用 PK 来完成。至少我是这样做的,我所有的表都有一个 ID,并且我正在使用该 ID 进行所有联接。
  • 那么最快的运行方式呢?
【解决方案2】:

老实说,“这取决于”是唯一有效的答案。存在并且不可能有硬性的“如果大于 X 加入则将其分解”规则。 (如果有,那么 X 将不得不每隔几年更改一次。我今天写的东西可能会让 10 年前的普通服务器陷入困境。)

话虽如此,确定截止点的最佳工具是经验。您编写、测试和试验代码的次数越多,CROSS JOIN 越熟悉“现在”必须使用的硬件和数据集,您就能够更好地编写最佳查询。这绝对不是说只有嘲笑 SQL-92 标准扩展的专家才能编写最佳查询。通过合理的努力,新程序员可以编写出“足够好”的代码,并且正如其名,一般来说,这对于大多数任务来说已经足够好了。

【讨论】:

  • 你是对的@Philip Kelley,但我没想到会有如此严格的东西,比如“你需要拆分的超过 X 个连接”。我期待某种类型的指南,即:(这些只是示例,我不知道这是否属实)如果您需要 group_concat,那么也许您应该拆分,如果您需要的不仅仅是 group_concat 和 distinct,那么肯定是更好的倍数查询,如果您有...“X”之类的情况,那么您可能是更好的多个查询等。也就是说,当您选择多个查询而不是多个连接时?在那种情况下最好使用自动提交假?使用子选择更好吗?
  • 那么最快的运行方式呢?
【解决方案3】:
Where is the limit? when a single query with Joins is worst than multiple queries?

这取决于优化器。随着查询变得越来越复杂,优化器选择不良执行计划的风险也会增加。

只需选择处理表格的顺序就可以在 N 中完成!方式,其中 N 是查询的表数。 5 个表有 120 种方式,10 个表高达 3628800。这只是优化器必须做出的决定之一。

【讨论】:

  • 所以你是说表(连接)的数量是一个限制?例如,如果您有 10 个连接,那么开始考虑拆分可能会更好?
  • 那么最快的运行方式呢?
  • 我的意思是当你加入许多表时,优化器做出错误选择的风险更大。对于 Oracle,我观察到大约 7 个以上的表。
【解决方案4】:

我会说,当您一次需要所有相关数据或相关数据非常大(例如带有图像的 LOBS...)时,您会加入而不是运行单独的选择。

如果您一次不需要所有相关的大型数据,请考虑“延迟初始化”,即在需要时查询该大型数据。

【讨论】:

  • 那么最快的运行方式呢?
【解决方案5】:

我还要说,当传输的数据比单个查询大几个数量级时。每行重复数据可能是一个严重的杀手。

我有一次查询,单独产生了大约 10 兆的传输数据,但使用内部连接,由于字段重复多次,产生了 900 兆的数据下载。该软件将 80% 的时间用于下载查询结果。这就是软件分析发挥作用的地方,它将告诉您在软件中花费最多的时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-15
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多