组合索引
来源:互联网 发布:云计算hcie待遇 编辑:程序博客网 时间:2024/05/14 23:48
回忆
记得刚工作的第一年,在一个市级政府部门驻场,一开发的哥们凑过来问我
“兄弟,我那个页面查询数据有点慢,帮我整整呗”
“查的啥?SQL给我瞧瞧”
“常口的,就是根据身份证号码和姓名去查,有时候一个条件,有时候会有两个条件,咋整?”
“额,我先看看,完事叫你”
然后套路就来了,身份证和姓名分别建索引,这样任意一个条件都不慌,再加一个身份证和姓名的组合索引,这样两个一起查也不慌,索引建完通知他再试试
“整完了,你再试试”
“嘿,比刚才快多了,没问题了,晚上整几杯?”
“who 怕 who啊”
唉,该傻逼的时候,我从没犹豫过
组合索引
组合索引一般包含两个或两个以上的列,创建组合索引时,列的排序也有讲究,第一列称为前导列,如果有可能,前导列最好是选择性高的列,有助于提高组合索引查询效率,如果是单个条件查询,而这个条件列恰好是组合索引的前导列,数据库就有可能使用这个索引,如果条件列是组合索引中的非前导列,也有可能使用这个索引进行索引跳跃扫描,不过效率一般不是很高。
搞清楚这个之后,那个常口查询的就很简单了,姓名列上建个索引,再建(身份证号码,姓名)组合索引,因为身份证号码的选择性比姓名要高,所以身份证号码作为前导列,这样无论是那种查询都能满足,其实,只建一个组合索引也可以,不过索引跳跃扫描效率无法保证。
测试
建立测试表,创建组合索引
SQL> create table test as select * from dba_objects;Table created.SQL> create index idx_test_id_name on test(object_id,object_name);Index created.前导列查询
SQL> select * from test where object_id = 100;Elapsed: 00:00:00.01Execution Plan----------------------------------------------------------Plan hash value: 3816852919------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 207 | 3 (0)| 00:00:01 || 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 207 | 3 (0)| 00:00:01 ||* 2 | INDEX RANGE SCAN | IDX_TEST_ID_NAME | 1 | | 2 (0)| 00:00:01 |------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 2 - access("OBJECT_ID"=100)Note----- - dynamic sampling used for this statement (level=2)Statistics---------------------------------------------------------- 0 recursive calls 0 db block gets 4 consistent gets 0 physical reads 0 redo size 1611 bytes sent via SQL*Net to client524 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
非前导列查询
SQL> select * from test where object_name='TEST';Elapsed: 00:00:00.02Execution Plan----------------------------------------------------------Plan hash value: 1357081020--------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |--------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 2 | 194 | 288 (1)| 00:00:04 ||* 1 | TABLE ACCESS FULL| TEST | 2 | 194 | 288 (1)| 00:00:04 |--------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - filter("OBJECT_NAME"='TEST')Statistics---------------------------------------------------------- 0 recursive calls 0 db block gets 1031 consistent gets 0 physical reads 0 redo size 1611 bytes sent via SQL*Net to client524 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed这里没有使用索引跳跃扫描,优化器认为全表扫描效率更高,下面使用hint,让该查询使用跳跃扫描
SQL> select /*+ index_ss(test)*/ * from test where object_name='TEST';Elapsed: 00:00:00.03Execution Plan----------------------------------------------------------Plan hash value: 3896253852------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 2 | 194 | 72058 (1)| 00:14:25 || 1 | TABLE ACCESS BY INDEX ROWID| TEST | 2 | 194 | 72058 (1)| 00:14:25 ||* 2 | INDEX SKIP SCAN | IDX_TEST_ID_NAME | 2 | | 72057 (1)| 00:14:25 |------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 2 - access("OBJECT_NAME"='TEST') filter("OBJECT_NAME"='TEST')Statistics---------------------------------------------------------- 0 recursive calls 0 db block gets408 consistent gets 0 physical reads 0 redo size 1614 bytes sent via SQL*Net to client524 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed使用索引跳跃扫描后,逻辑读虽然减少许多,但是cpu耗费比全表扫描高太多。
另外,毫无疑问,组合索引的代价比单列索引更高,无论是空间上还是DML操作上,但是在以查询为主的业务上,who care?
0 0
- 组合索引
- 组合索引
- 组合索引
- 组合索引
- 组合索引
- 组合索引
- 组合索引
- 组合索引
- 组合索引
- 单键索引还是组合索引
- 单键索引还是组合索引
- MySQL索引之组合索引
- 单键索引还是组合索引
- 组合索引,索引内过滤
- 单键索引还是组合索引
- mongodb组合索引优化
- mysql创建组合索引
- 利用组合索引优化
- C#中virtual和abstract的区别
- 有用的框架
- STL容器内元素条件
- MongoDB主要启动参数说明
- 1789 Doing Homework again 倒叙思想的贪心算法
- 组合索引
- VC++中"using namespace std"有什么用的
- mesos源码编译及配置及marathon配置安装
- 欢迎使用CSDN-markdown编辑器
- kinect2.0开发笔记(二) 获取彩色图和深度图
- 集群相关
- 遮罩层DIV+CSS
- Spring Dao异常分类
- 访问远程sqlserver的链接服务器设置