2012-12-11 61 views
2

有双向做多表查询:问题关于多表查询性能

查询1:

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

查询2:

每一行:

select t1.a from t1 

d o另一个查询:

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

当表格非常大时,哪一个表现更好?

+2

执行1次查询是比执行许多更快。如果没有,那么你需要添加索引到你的表中。 –

+0

查询2是什么?这是一个子选择,还是你打算使用游标循环'每行'? – mipe34

+0

如果您唯一的考虑因素是在数据库上运行的一个查询,那么第一个查询会运行得更快,但是,如果这是一个多用户环境,并且该表非常大,那么当第一个查询运行得更快时,它可能会导致更长的锁定,与其他用户的死锁,您将需要确保指定相关的表提示来管理锁。 – GarethD

回答

1

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

DBMS知道每个数据库中有多少个元组,并且有一种方法来估计结果将具有的元组数量。现代DBMS具有非常复杂的算法,负责找到执行任何查询(规划器)的最有效方法。除非你知道你在做什么,为什么你在做(即你知道你的算法会比DBMS运行得更快,更重要的是,为什么),你应该让DMBS完成它的工作。

回答你的问题更准确地说:

您的查询#1可以与答案不同的方法,这取决于表的大小。让我们假设这两者都是巨大的。要解决的一个方法是使用基于排序的连接:基于连接属性对两个表进行排序,然后合并它们。这基本上相当于在每个表上进行合并排序所花费的时间。每张表的每页将被读取和写入几次(取决于您在DMBS中有多少缓冲空间)。因此,T1和T2中的每个元组都会被读取/写入,比如十几次。

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

如果你有一个在T2上的索引,你可以期望为T1中的每个元组读一些页面。因此,查询的代价是读取T1的开销,然后对于T1中的每个元组,需要读取几页(2-5)才能找到T2中的匹配元组。

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

这是一种常见的幼稚DBMS程序员的失误:让DB做了一点工作,那么每一个元组,做更多的工作。

相反,您应该考虑让数据库管理系统在尽可能少的查询中完成所有处理。它会在业绩中得到回报。

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

--dmg