关于复合索引中的2个索引列谁在前谁在后的进一步讨论--实践篇

关于复合索引中的2个索引列谁在前谁在后的进一步讨论--实践篇:

上一次在长老的QQ群里边说了这么一个例子:

create table test_pk( id varchar2(10), create_dt date);

alter table test_pk modify (id varchar2 (30 ));

insert into test_pk select object_id, sysdate from dba_objects;
commit

需要执行的查询是:

select * from test_pk where create_dt> sysdate- 1/1440 and id like '13%'

索引有如下两个:当然任意时刻,只存在下面的任意一个。

create index idx_test_pk on test_pk(create_dt, id);
create index idx_test_pk_id_create_dt on test_pk(id,create_dt);

也就是说:两个索引列的位置是反着的

首先要明确的一个问题:

where create_dt> sysdate- 1/1440 and id like ‘13%‘

不论 create_dt 和id 谁在前谁在后,这样的where条件是能走索引的。

其次需要明确的问题:

create_dt 和id  这两个索引列,哪个在前面时,如上查询的效率高?(当然,前提是:不考虑其他查询!!!)

经过实际验证,发现id 在前面时,如上查询的buffer get要比 create_dt 在前面时的 buffer get 低。

create index idx_test_pk_id_create_dt on test_pk(id,create_dt); ---bg 是 6

create index idx_test_pk on test_pk(create_dt,id); ---bg 是29.5

那么为啥id 在前面时的复合索引,查询语句的buffer get 要低呢?

原因不在于 id是什么数据类型的,

原因在于where条件中id的表现形式: id like ‘13%‘ ,相比而言,create_dt的表现形式是create_dt> sysdate- 1/1440

大家知道:

index是有序的,那么 id like ‘13%‘ 去索引的leaf block 检索时,检索过的leaf block的数量 一般是要比 create_dt> sysdate- 1/1440 (也就是create_dt在前面) 去索引的leaf block 检索过的leaf bock 的数量要少,正是这个原因,才导致id列在前面时的buffer get 要小。

时间: 2024-12-18 20:22:01

关于复合索引中的2个索引列谁在前谁在后的进一步讨论--实践篇的相关文章

[转帖]SQL Server 索引中include的魅力(具有包含性列的索引)

SQL Server 索引中include的魅力(具有包含性列的索引) http://www.cnblogs.com/gaizai/archive/2010/01/11/1644358.html 上个月刚发现sql2016 之前仅支持 索引包含 16个键 (之后支持32个键) 这个月发现 可以 使用include 的方式来处理. 开文之前首先要讲讲几个概念 [覆盖查询] 当索引包含查询引用的所有列时,它通常称为“覆盖查询”. [索引覆盖] 如果返回的数据列就包含于索引的键值中,或者包含于索引的键

SQL Server索引 - 聚集索引、非聚集索引、非聚集唯一索引 <第八篇>

聚集索引.非聚集索引.非聚集唯一索引 我们都知道建立适当的索引能够提高查询速度,优化查询.先说明一下,无论是聚集索引还是非聚集索引都是B树结构. 聚集索引默认与主键相匹配,在设置主键时,SQL Server会默认在主键列创建聚集索引.但是可以手动更改为在任意一个列创建聚集索引,然后在另一个字段或多个字段上定义主键.这时主键将会被作为一个唯一的非聚集索引(唯一索引)被创建.通过指定NONCLUSTERED关键字就可以做到. CREATE TABLE MyTableKeyExample { Colu

B树在数据库索引中的应用剖析(转载)

引言 关于数据库索引,随便Google一个Oracle index,Mysql index总有大量的结果出来,其中不乏某某索引之n条经典建议.笔者认为,较之借鉴,在搞清楚了自己的需求的基础上,对备选方案的原理有个尽可能深入全面的了解会更有利于我们的选择和决策.因为某种方案或者技术呈现出某种优势(包括可能没有被介绍到但一定存在的限制),不是定义出来的,而是因为其实现机制决定的.就像LinkedList和ArrayList分别适用于什么应用不是Document里面定义的,是由其本身的结构决定的.数据

mongoose中给字段添加索引的方法

mongoose中给字段添加索引的方法有两种,一种通过在定义schema的时候配置,如: 1 var animalSchema = new Schema({ 2 name: String, 3 type: String, 4 tags: { type: [String], index: true } 另一种通过index方法添加索引,如给name和type字段添加索引(1和-1分别表示升序索引和降序索引): animalSchema.index({ name: 1, type: -1 });

非聚集索引中的临界点(Tipping Point)

什么是临界点? 注意,我要说的问题是非聚集索引的执行计划从Seek+Lookup变成Table/Clustered Index Scan的临界点.SQL Server的访问数据的IO最小单元是页. 我们知道聚集索引的叶级是数据页,非聚集索引的叶级是指向数据行的指针.所以通过聚集索引获取数据时,就是直接访问聚集索引本身,而通过非聚集索引获取数据时,除了访问自身,还要通过指针去访问数据页.这个过程就是RID/Key Lookup.而此Lookup是一个单页操作,即每次使用一个RID/Key,然后去访

对mysql联合索引中的字段进行合理排序

在MySQL的where条件中,有时会用到很多的条件,通常为了加快速度会把这些字段放到联合索引中,可以更快的提高搜索速度: 但是对联合索引中字段顺序的合理排序,便更能提高速度 例子:select * from table where (groupid=1000) and (userid=500) and (time=140012345) 建立的索引也通常很随性的就按照where条件中字段的顺序建立 ALTER  TABLE  table  ADD  INDEX g_u_time_index(gr

关于mysql中or条件和索引

参考boke:http://blog.csdn.net/hguisu/article/details/7106159 1 .where 语句里面如果带有or条件, myisam表能用到索引, innodb不行.(在mysql5.6下测试如此) CREATE TABLE IF NOT EXISTS `a` ( `id` int(1) NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NULL, `aNum` char(20) DEFAULT NULL, PRIM

[Elasticsearch] 向已存在的索引中添加自定义filter/analyzer

问题描述 随着应用的不断升级,索引中的类型也会越来越多,新增加的类型中势必会使用到一些自定义的Analyzer.但是通过_settings端点的更新API不能直接在已经存在的索引上使用.在sense中进行更新时会抛出异常: PUT /symbol { "settings": { "analysis": { "filter": { "edgengram": { "type": "edgeNGram&

java.sql.SQLException: 索引中丢失 IN 或 OUT 参数:: 1解决办法

java.sql.SQLException: 索引中丢失  IN 或 OUT 参数:: 1 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:125) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:162) at oracle.jdbc.driver.OraclePreparedStatement.pr