有关多表查询性能的问题

时间:2012-12-11 09:36:26

标签: sql optimization sql-optimization

有多种方法可以进行多表查询:

查询1:

select t1.a, t2.b from t1, t2 where t1.a = t2.a

查询2:

每行

select t1.a from t1

再做一次查询:

select t2.b from t2 where t2.a = '??'

当表非常大时,哪一个具有更好的性能?

1 个答案:

答案 0 :(得分:1)

您应该始终让DBMS在单个查询中尽可能多地工作。

DBMS知道每个数据库中有多少元组,并且有办法估计结果将具有的元组数。现代DBMS具有非常复杂的算法,负责找到执行任何查询的最有效方式(规划器)。

除非你知道自己在做什么,以及为什么要这样做(即你知道你的算法运行速度比DBMS快,更重要的是,为什么),你应该让DMBS完成它的工作。

更准确地回答您的问题:

您的查询#1可以使用各种方法进行回答,具体取决于表的大小。让我们假设两者都是巨大的。一种解决方法是使用基于排序的连接:根据连接属性对两个表进行排序,然后合并它们。这基本上等于在每个表上进行合并排序所花费的时间。每个表的每个页面将被读取和写入几次(取决于您在DMBS中可用的缓冲区空间)。所以T1和T2中的每个元组都会被读/写,十几次。

如果我们实现您的方法,那么将会有与T1大小一样多的查询。让我们假设T2没有索引,因此查询将在T2 T1时间读取每个元组。

如果T2上有索引,则可以在T1中为每个元组读取几页。因此,查询的成本是读取T1的成本,然后对于T1中的每个元组,您需要阅读几页(2-5)以在T2中找到匹配的元组。

如果T1非常小且T2非常大,查询2会更快!但是,DBMS会发现,并将完全执行您的算法来回答Q1(它被称为基于循环的连接)。此外,您发送给DBMS的每个查询都需要时间来处理(方法1没有的开销)。

这是一个普通的天真DBMS程序员的错误:让DB做一点工作,然后为每个元组做一些工作。

相反,您应该考虑让DBMS尽可能少地进行所有处理。它会在性能上得到回报。

最后,如果您真的对性能感兴趣,请抓住您喜爱的DMBS的文档并阅读它如何进行查询评估,以及如何改进它。

- DMG