今天我又被问到一个全表查询的问题。这次好在不是前后%,仅仅前%。比如需求是要手机尾号或者卡号尾号。我其实不理解为什么有这样的需求。不过比起前后%这样的还算可以。我先说一下这个是在Oracle中的,MySQL据我所知没有。PG等其他数据库我需要研究看看。这个主要是说明我怎么构思的。
SQL> create table xuexiaogang3 (id int ,a int ,b varchar2(10));
Table created
SQL> create index x3 on xuexiaogang3 (id);
Index created
SQL> exec xxg3;存储过程写入100万数据
PL/SQL procedure successfully completed
SQL> exec dbms_stats.gather_table_stats(ownname=>'XXG',tabname=>'XUEXIAOGANG3');
PL/SQL procedure successfully completed
收集统计信息。然后我们查询id样本数据。如图1,大家可以看到数据大致长这个样子。
图1
我们按照ID查询,因为ID是有索引的,那么看到执行计划使用了索引X3。如图2
图2
而如果查询B列,由于B列没有索引,必然是全表扫描。如图3.
图3
更加不用说图4中的前%,那么就更加是全表查询了。
图4
在这种情况下要处理我们只查尾号,那么就用反向索引。如图5.
图5
当然我们的SQL也要改写,改写成如图6。我们可以看到结果和图4的结果一样。区别是这样不是全表查。使用到了xd3的反向索引。
这个案例表明前%,我们也是可以解决的。只要不是前后同时%,那么就要涉及到特殊处理了。
当然这个功能不是新功能,也不是主流功能,是一个小众功能,但是依然有很多人不知道。如果在MySQL中没有这个功能怎么办?
那么我的建议是新建一列,把要处理的尾号单独存储。查询的时候查这个尾号列。
Oracle强大给了我们很多开发和运维便利的方法,但是很多人不知道。
这些功能值得大家去用,尽管到现在还有很多人不知道。所以作为Oracle-ACE应该推广在Oracle和MySQL上的使用。