知识卡片
IS_EMPTY/COUNT等价关系及COUNT替代EXISTS的性能陷阱
内容
量词化本质上都能用其他已有运算符表达。若系统支持[[TABLE_DUM与TABLE_DEE
关系代数中的0]]里的IS_EMPTY运算符,就不需要单独支持量词:
EXISTS x(p)≡NOT(IS_EMPTY(X WHERE p)),FORALL x(p)≡IS_EMPTY(X WHERE
NOT(p))(X是x覆盖的集合)——SQL的EXISTS支持本质上正是这条等价关系的具体
实现:EXISTS(tx)先算出tx代表的表t,再判定t是否非空。若系统支持COUNT
聚集运算符,同样不需要量词:EXISTS x(p)≡COUNT(X WHERE p)>0,
FORALL x(p)≡COUNT(X WHERE p)=COUNT(X),UNIQUE x(p)≡COUNT(X WHERE
p)=1。但书中特别提醒:把量化表达式替换成COUNT形式在实践中往往是一个性能
陷阱——WHERE EXISTS(SELECT * FROM SP WHERE SP.SNO=S.SNO)只需要找到第
一条匹配记录就能立刻确定为TRUE并停止扫描;改写成逻辑等价的
WHERE(SELECT COUNT(*) FROM SP WHERE SP.SNO=S.SNO)>0却字面上要求系统
先把全部匹配行数完统计出来、再判断这个数字是否大于0,这实质上要求了一次
完整的计数扫描,而不是”找到一个就能提前终止”的短路检查——建议是:使用
COUNT要格外小心,尤其在EXISTS本来就是逻辑上更贴切的选择时,不要为了图
省事而改用COUNT。这条等价关系体系也支撑了关系完备性(relational
completeness)这一核心理论结论:关系代数的每个运算符都能用本章的逻辑
术语精确重述,因此任何关系代数表达式都有逻辑等价的关系演算表达式;反过来
同样成立——两种形式化方法因此在表达能力上完全等价,都是”关系完备”的:
任意复杂的查询理论上都不需要借助任何显式的迭代循环或分支就能表述出来,
这正是关系型语言(至少在理论上)能让终端用户直接查询数据库、无需专门
编程支持的根本依据。