近日系统频报缓慢,前台受理因失败频频而不断冲正。因系统业务量不大,白天中午做了一下索引重建,查询了一下似乎速度快了些。
第二天有人报障,称受理时提示“售完”,但实际系统仍有库存。查了一下数据库,要卖的卡确实有很多未售的库存,从受理日志提取出查询语句,发现确实查不到数据。查询语句如下:
SELECT a.seq,a.f1,a.f2,a.f3
FROM a
WHERE a.seq = (SELECT MIN(seq)
FROM a
WHERE a.f1 = '100'
AND a.f2 = 'S0A'
AND a.f3 = 'S0A')
AND a.f1 = '100'
AND a.f2 = 'S0A'
AND a.f3 = 'S0A'
该sql主要是查找seq最小的记录信息。
诡异的是中间查最小值的那段子查询,查出来的min(seq)的f2字段竟然是'S0C'值,而不是'S0A',即子查询中的过滤条件
AND a.f2 = 'S0A'
竟然不起作用。
同样的语句在不同机器上查了多次,结果都显示一样。而将f1的值“100”改为其他值,查询结果又正常。因该语句从系统上线就没有改过,查询过无数次,可以肯定以前的查询结果是正确的,问题原因应该与近期的操作有关。考虑到该语句使用的索引恰好是重建的索引,而查出来的min(seq)值的操作时间刚好处于索引重建的时间段,所以怀疑是索引重建导致问题产生。
于是,找了个较空闲的时间又做了一次索引重建,
Alter index IX1 rebuild online tablespace idx_tablespace;
只花了八十几秒。再查询同样的语句,结果恢复正常。
结论:重建索引还是要找个空闲时间来做。万一碰上该索引的某条记录正在事务处理中,可能会导致查询出错。