数据库-表达式计算
象这样一个sql:
select * from account r where balance<2500 join customer s on r.customer-name=s.name
一个表达式中包含多个运算,该怎样计算呢?
一种方法是以一定的顺序每次执行一个操作,每次计算的结果被实体化到一个临时关系中以备后用。实体化计算的代价包括所有运算的代价和把中间结果写回磁盘的代价。其中磁盘I/O的代价很高。
另一种方法是在流水线上同时执行多个运算,一个运算结果传递给下一个,而不必保存到临时关系中。如例所示的连接运算,其左端输入来自流水线,由于是流水线输入,处理连接运算所需的输入不能一下子全部获得。这限制了所能使用的连接算法,例如归并连接输入前未排序是不能使用的。使用嵌套循环索引可以,对于流水线输入关系的每一个元组可能都需要一次磁盘访问。代价为nr*HTs,HTs是s上索引的高度。若用实体化方法,采用散列连接,则执行大家为3(br+bs),将关系r写出的代价是br。当nr比4br+3bs大很多事,实体化方法的代价较小。如果流水线输入的元组按连接属性排序,并且连接条件是等值连接,则亦可使用归并连接。若两个输入均为流水线输入,且是等值连接已排序,可用流水线连接算法:
while not doner or ont dones do
begin
if 队列空 then等待,直到队列非空;
t=队列中的头一项;
if t=Endr,then doner=true;
else if t=Ends then dones=true;
else if t属于输入关系r then
begin
r=r∪|t|;
result=result∪(t连接s);
end
else
begin
s=s∪|t|;
result=result∪(t连接s);
end
end
两个关系可用输入元组在同一队列中排队等待处理。
对于复杂的连接运算,好的连接运算顺序对于减小临时结果的大小是很重要的。