SQL中like语句的索引使用
2013-02-28 16:27
330 查看
1、尽量不要使用 like '%..%'
2、对于 like '..%..' (不以 % 开头),Oracle可以应用 colunm上的index
3、对于 like '%...' 的 (不以 % 结尾),可以利用 reverse + function index 的形式,变化成 like '..%' 代码
建测试表和Index。
注意:重点在于带reverse的function index。同时,一定要使用CBO才行......
SQL> select reverse('123') from dual;
REVERSE('123')
--------------------------------
321
1 row selected.
SQL> create table test_like as select object_id,object_name from dba_objects;
Table created.
SQL> create index test_like__name on test_like(object_name);
Index created.
SQL> create index test_like__name_reverse on test_like(reverse(object_name));
Index created.
SQL> analyze table test_like compute statistics for table for all indexes;
Table analyzed.
SQL> set autot trace
--常量开头的like , 会利用index ,没问题......
SQL> select * from test_like where object_name like AS%';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=655 Bytes=15720)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_LIKE' (Cost=2 Card=655Bytes=15720)
2 1 INDEX (RANGE SCAN) OF 'TEST_LIKE__NAME' (NON-UNIQUE) (Cost=2 Card=118)
-- 开头和结尾都是%,对不起,很难优化
SQL> select * from test_like where object_name like '%%';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=655 Bytes=15720)
1 0 TABLE ACCESS (FULL) OF 'TEST_LIKE' (Cost=6 Card=655 ytes=15720)
-- 以常量结束,直接写的时候是不能应用index的
SQL> select * from test_like where object_name like '%S';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=655 Bytes=15720)
1 0 TABLE ACCESS (FULL) OF 'TEST_LIKE' (Cost=6 Card=655 Bytes=15720)
--'以常量结束的,加个reverse 函数,又可以用上index了'
SQL> select * from test_like where reverse(object_name)like reverse('%AS');
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=655 Bytes=15720)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_LIKE' (Cost=2 Card=655 Bytes=15720)
2 1 INDEX (RANGE SCAN) OF 'TEST_LIKE__NAME_REVERSE' (NON-UNIQUE) (Cost=2 Card=118)
2、对于 like '..%..' (不以 % 开头),Oracle可以应用 colunm上的index
3、对于 like '%...' 的 (不以 % 结尾),可以利用 reverse + function index 的形式,变化成 like '..%' 代码
建测试表和Index。
注意:重点在于带reverse的function index。同时,一定要使用CBO才行......
SQL> select reverse('123') from dual;
REVERSE('123')
--------------------------------
321
1 row selected.
SQL> create table test_like as select object_id,object_name from dba_objects;
Table created.
SQL> create index test_like__name on test_like(object_name);
Index created.
SQL> create index test_like__name_reverse on test_like(reverse(object_name));
Index created.
SQL> analyze table test_like compute statistics for table for all indexes;
Table analyzed.
SQL> set autot trace
--常量开头的like , 会利用index ,没问题......
SQL> select * from test_like where object_name like AS%';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=655 Bytes=15720)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_LIKE' (Cost=2 Card=655Bytes=15720)
2 1 INDEX (RANGE SCAN) OF 'TEST_LIKE__NAME' (NON-UNIQUE) (Cost=2 Card=118)
-- 开头和结尾都是%,对不起,很难优化
SQL> select * from test_like where object_name like '%%';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=655 Bytes=15720)
1 0 TABLE ACCESS (FULL) OF 'TEST_LIKE' (Cost=6 Card=655 ytes=15720)
-- 以常量结束,直接写的时候是不能应用index的
SQL> select * from test_like where object_name like '%S';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=655 Bytes=15720)
1 0 TABLE ACCESS (FULL) OF 'TEST_LIKE' (Cost=6 Card=655 Bytes=15720)
--'以常量结束的,加个reverse 函数,又可以用上index了'
SQL> select * from test_like where reverse(object_name)like reverse('%AS');
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=655 Bytes=15720)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_LIKE' (Cost=2 Card=655 Bytes=15720)
2 1 INDEX (RANGE SCAN) OF 'TEST_LIKE__NAME_REVERSE' (NON-UNIQUE) (Cost=2 Card=118)
相关文章推荐
- 强制SQL语句使用某个索引
- SQL语句优化-重点在于使用到索引
- 在ASP中使用SQL语句之3:LIKE、NOT LIKE和 BETWEEN
- 在优化SQL语句中使用虚拟索引
- oracle数据库查询Sql语句是否使用索引及常见的索引失效的情况
- Sql Server 索引使用情况及优化的相关Sql语句分享
- SQL Server 索引结构及其使用(二) 改善SQL语句第1/3页
- oracle sql 中 like语句使用记录
- SQL Server 索引使用分析(2)- 改善SQL语句,防止索引失效
- 教您如何使用SQL中的SELECT LIKE like语句
- 使用SQL语句查询某表中所有的主键、唯一索引以及这些主键、索引所包含的字段(转)
- like语句百分号前置会使用到索引吗?
- sql语句中导致索引失败的一些错误使用方式
- 总结mysql不使用索引情况以及如何优化sql语句
- sql语句优化之一:尽量使用索引避免全表扫描
- sql语句中like的使用
- C# SQL 语句参数化使用 like 报错
- SQL SERVER 使用索引调优 Transaction Sql 语句
- 教您如何使用SQL中的SELECT LIKE like语句
- Lambda表达式Contains方法(等价于SQL语句中的like)使用注意事项