下案例,用来判断会计账目是否存在“金额不平”的情况,虽然可选择xìng很高,但
不适合加索引。
此例中,有个表glreport,该表包含一个应为0的字段amount_diff。此查询的目的是要追踪会计错
误,并找出amount_diff不是0的记录。既然使用了现代的DBMS,直接把账目对应成表,并应用
从前“纸笔记账”的逻辑,实在有点问题;但很不幸,我们经常遇到这种有问题的数据库。无论
设计的质量如何,像amount_diff这样的字段
通常不应加索引,因为在理想情况下每条记录的amount_diff字段都是0。此外,amount_diff字
段明显是“非规范化”设计的结果,大量计算要cāo作该字段。维护一个计算字段上的索引,代价
要高于静态字段上的索引,因为被修改的键会在索引内“移动”,于是索引要承受的开销比简单
节点增/删要高。
总结:并非所有明确的条件都适合加索引。特别是,频繁更新的字段会增加索引维护的成本。
回到例子。开发者有天来找我,说他已最佳化了以下Oracle 查询,并询问过专家建议:
select
total.deptnum,
total.accounting_period,
total.ledger,
total.cnt,
error.err_cnt,
cpt_error.bad_acct_count
from
-- First in-line view
(select
deptnum,
accounting_period,
ledger,
count(account) cnt
from
glreport
group by
deptnum,
ledger,
accounting_period) total,
-- Second in-line view
(select
deptnum,
accounting_period,
ledger,
count(account) err_cnt
from
glreport
where
amount_diff <> 0
group by
deptnum,
ledger,
accounting_period) error,
-- Third in-line view
(select
deptnum,
accounting_period,
ledger,
count(distinct account) bad_acct_count
from
glreport
where
amount_diff <> 0
group by
deptnum,
ledger,
accounting_peri