小编典典

Joel Spolsky文章中的SQL问题

sql

摘自Joel Spolsky关于泄漏抽象的
文章

[C]某些SQL查询比其他逻辑上等效的查询慢数千倍。一个著名的例子是,即使结果集指定为“ where a = b and b = c and a =
c”,某些SQL Server的速度也比仅指定“ where a = b and b = c”要快得多。是一样的

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


阅读 139

收藏
2021-04-22

共1个答案

小编典典

显然,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服务器可以有一个逻辑推断模块,该模块也可以推断这意味着a =
c。然后,它可能会执行b,c的联接,然后执行a,c的联接(同样,这是一个假设的情况)。这需要进行500x20 +
1000x20的比较,然后进行交集计算。如果期望的#(a = c)较小(由于某些领域的知识),则第二个查询将更快。

总的来说,我的答案变得太长了,但这意味着SQL查询优化不是一项微不足道的任务,这就是为什么某些SQL Server可能做得不好的原因。

可以在http://en.wikipedia.org/wiki/Query_optimizer上找到更多信息,或者可以从数据库的一些期望中找到更多信息。

但是从哲学上讲,SQL(作为抽象)是要隐藏实现的所有方面。它的意思是声明性的(SQL
Server本身可以使用sql查询优化技术来重新定义查询,以使其更加高效)。但是在现实世界中并非如此-数据库查询通常必须由人类重写以提高它们的效率。

总体而言,本文的重点是,抽象只能如此出色,而没有完美的抽象。

2021-04-22