【问题标题】:SQL (any) Request for insight on a query optimizationSQL(任何)请求了解查询优化
【发布时间】:2009-05-14 21:17:57
【问题描述】:

由于大量信息被连接在一起,我的查询速度特别慢。但是,我需要以 id in 的形式添加 where 子句(从表中选择 id)。

我想知道以下是否有任何收获,更紧迫的是,它是否会给出预期的结果。

select a.* from a where a.id in (select id from b where b.id = a.id)

作为替代:

select a.* from a where a.id in (select id from b)

更新: MySQL 不能更具体抱歉 表 a 实际上是 7 个不同表之间的连接。 * 用于举例

编辑,b 没有被选中

【问题讨论】:

  • 注意:它们是简化的,a 实际上是 7 个不同的订单/客户/付款相关表之间的连接
  • 是的,我想知道为什么 7 个不同表之间的连接可能会很慢 :-)
  • 为什么会因为7个表而变慢?那没什么;)
  • 打哈欠谁会记下来?为什么?

标签: sql optimization query-optimization sql-optimization


【解决方案1】:

您的问题是关于这两者之间的区别:

select a.* from a where a.id in (select id from b where b.id = a.id)

select a.* from a where a.id in (select id from b)

前者是一个相关子查询。可能会导致 MySQL 对a 的每一行执行子查询。

后者是一个不相关子查询。 MySQL 应该能够执行一次并缓存结果,以便与a 的每一行进行比较。

我会使用后者。

【讨论】:

  • 谢谢。这解释了一些事情。
【解决方案2】:

您列出的两个查询都相当于:

select a.* 
from a 
inner join b on b.id = a.id

几乎所有优化器都会以相同的方式执行它们。

您可以发布一个真正的执行计划,这里的某个人可能会给您一种加快执行计划的方法。如果您指定您正在使用的数据库服务器,它会有所帮助。

【讨论】:

  • mysql innodb,无法发布执行计划抱歉。
  • 标题说 sql (any) 因为它是一个理论问题,
  • Lou 指出 b 可能有重复的 ID,因此连接不会产生相同的结果。
【解决方案3】:

YMMV,但我经常发现使用 EXISTS 而不是 IN 可以使查询运行得更快。

SELECT a.* FROM a WHERE EXISTS (SELECT 1 FROM b WHERE b.id = a.id)

当然,如果不查看查询的其余部分和上下文,这可能不会使查询变得更快。

JOINing 可能是一个更可取的选择,但如果 a.id 在 b 的 id 列中出现多次,您将不得不在其中抛出一个 DISTINCT,并且您很可能会在优化方面倒退。

【讨论】:

  • 是什么让您认为这会运行得更快?
【解决方案4】:

我永远不会使用这样的子查询。加入会快得多。

select a.*
from a 
join b on a.id = b.id

当然也不要使用 select * (尤其是在进行连接时不要使用它,因为至少有一个字段重复),它会浪费网络资源来发送不需要的数据。

【讨论】:

  • 是什么让您认为这会运行得更快?
  • 加入会更快,@ * 使用,例子被简化了。
  • 执行计划相同,此示例根据 b 的结构呈现潜在的重复记录。
【解决方案5】:

你看过执行计划吗?

怎么样

select a.* 
from a 
inner join b
on a.id = b.id

大概 id 字段是主键?

【讨论】:

    【解决方案6】:
    Select a.* from a
    inner join (Select distinct id from b) c
    on a.ID = c.AssetID
    

    我尝试了所有 3 个版本,它们的运行情况大致相同。执行计划相同(内连接,IN(子查询中有无where子句),Exists)

    由于您没有从 B 中选择任何其他字段,我更喜欢使用 Where IN(Select...) 任何人都会查看查询并知道您要做什么(仅在 b 中的 if 中显示。 )。

    【讨论】:

    • 我的解释为连接的所有内容提供了简单的选择类型,而对于“in select”,它提供了所有表的主要类型,然后是依赖子查询。即使使用 distinct,加入似乎也是更快的选择。
    【解决方案7】:

    您的问题很可能在“a”中的七个表中

    使 FROM 表包含“a.id” 进行下一个连接:inner join b on a.id = b.id

    然后加入其他六个表。

    如果您需要真正的帮助,您确实需要显示整个查询、列出所有索引以及每个表的大致行数

    【讨论】:

    • 没看到,我只是在问我的问题中显示的两者之间的区别。 'a' 部分没有损坏 正确使用了索引。从某种意义上说,查询可以被优化得更慢,因为它的结果集很大,所以它并不慢。列出数据库模式在这里并不重要,它被简化为我感兴趣的部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2013-01-10
    相关资源
    最近更新 更多