知识卡片

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)>0FORALL 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)这一核心理论结论:关系代数的每个运算符都能用本章的逻辑 术语精确重述,因此任何关系代数表达式都有逻辑等价的关系演算表达式;反过来 同样成立——两种形式化方法因此在表达能力上完全等价,都是”关系完备”的: 任意复杂的查询理论上都不需要借助任何显式的迭代循环或分支就能表述出来, 这正是关系型语言(至少在理论上)能让终端用户直接查询数据库、无需专门 编程支持的根本依据。

参考来源

- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第10章"SQL与逻辑" 10.7节"一些等价关系"、10.7.1节"关系的完备性"(源文件:OEBPS/text00115.html) - 结论依据:原文明确"EXISTS x(p)≡NOT(IS_EMPTY(X WHERE p))…… EXISTS x(p)≡COUNT(X WHERE p)>0……我们真的没有希望系统进行全体计数 然后再去看计数是否大于0……使用COUNT要格外小心;尤其在EXISTS更为逻辑 正确的情况下,不要使用COUNT……两种形式化方法是逻辑等价的:两者都是所谓 的'关系完备的'"。 - 原始内容:EXISTS x(p)≡COUNT(X WHERE p)>0……使用COUNT要格外小心; 尤其在EXISTS更为逻辑正确的情况下,不要使用COUNT……两种形式化方法是 逻辑等价的:两者都是所谓的"关系完备的"。