代码之家  ›  专栏  ›  技术社区  ›  jason

JoelSpolsky文章中的SQL问题

  •  10
  • jason  · 技术社区  · 17 年前

    乔尔·斯波尔斯基的 article

    [C] 某些SQL查询的速度比其他逻辑上等价的查询慢数千倍。一个著名的例子是,即使结果集相同,但如果指定“where A=b和b=c以及A=c”,某些SQL Server的速度也要比仅指定“where A=b和b=c”的速度快得多。

    有人知道这件事的细节吗?

    3 回复  |  直到 14 年前
        1
  •  27
  •   amit kumar    17 年前

    显然,a=b和b=c=>a=c-这与传递闭包有关。Joel指出的一点是,一些SQL服务器在优化查询方面很差,因此一些SQL查询可能使用“额外”限定符编写,如示例中所示。

    在本例中,请记住,上面的a、b和c经常引用不同的表,并且像a=b这样的操作作为联接执行。假设表a中的条目数为1000,b为500,c为20。然后,a,b的连接需要1000x500行比较(这是我愚蠢的示例;实际上可能有更好的连接算法,可以大大降低复杂性),而b,c需要500x20行比较。优化编译器将确定应首先执行b,c的联接,然后在a=b上联接结果,因为b=c的预期行较少。总的来说,(b=c)和(a=b)分别有大约500x20+500x1000个比较。之后,必须计算返回行之间的交点(我猜也是通过连接,但不确定)。

    假设Sql server可以有一个逻辑推理模块,该模块还可以推断这意味着a=c。然后它可能会执行b,c的连接,然后执行a,c的连接(这也是一个假设的情况)。这将需要500x20+1000x20比较,然后进行交点计算。如果预期的#(a=c)较小(由于某些领域知识),则第二次查询将快得多。

    http://en.wikipedia.org/wiki/Query_optimizer 或者从一些数据库中读取。

    但从哲学上讲,SQL(作为一种抽象)意味着隐藏实现的所有方面。它是声明性的(SQL服务器本身可以使用SQL查询优化技术来重新表述查询,以提高效率)。但在现实世界中,数据库查询并不经常需要人工重写以提高效率。

        2
  •  18
  •   Joel Coehoorn    17 年前

    这里有一个更简单的解释,所有内容都在一个表中。

    假设A和C都有索引,但B没有。如果优化器不能意识到A=C,那么它必须对这两个WHERE条件使用非索引的B。

        3
  •  1
  •   Jonathan Leffler    17 年前

    我认为“确定”这个词在这里是有效的术语。为了让优化器真正理解a=c,它必须解析a的等式,然后将a的等式一直连接到传递关系中的“c”,以推导出关系。