组合索引中列的顺序对执行计划的影响比较大。下面先简单介绍组合索引的适用场景,后面再根据一个具体的 SQL 说说组合索引中列的顺序对 DM 执行计划的影响。
兹有 Index (A,B,C) ——组合索引多字段是有序的,并且是个完整的BTree 索引。
下面条件可以用该组合索引查询:
A>5
A=5 AND B>6
A=5 AND B=6 AND C=7
A=5 AND B IN (2,3) AND C>5
下面条件将不能用该组合索引查询:
下面条件将能用部分组合索引查询:
兹有组合索引 Index(A,B)。下面条件可以用该组合索引排序:
下面条件不能用该组合索引排序:
先看一条查询的 SQL:
SELECT count(*)FROM UCAP_DEPT
WHERE DEPT_UNPT_UNID ='00000000000000000000000000000000' OR
( DEPT_BELONGTO = '00000000000000000000000000000000' AND DEPT_TYPE ='2')
OR (DEPT_BELONGTO IN
(SELECT T.DEPT_UNID
FROM UCAP_DEPT T
WHERE T.DEPT_BELONGTO ='00000000000000000000000000000000' AND T.DEPT_TYPE ='2'
)
);
分析下这条 SQL 该如何建索引,根据 UCAP_DEPT 这个表中的记录数,可以判断通过 DEPT_BELONGTO 能够过滤很多记录,这条 SQL 最好的计划应该是先将以下结果查询出来:
SELECT T.DEPT_UNID FROM UCAP_DEPT T WHERE T.DEPT_BELONGTO ='00000000000000000000000000000000' AND T.DEPT_TYPE ='2'
查询结果出来后,再进行后续查询,先建索引:
create index IDX_UCAP_DEPT_TO_TYPE on ucap_price.UCAP_DEPT(DEPT_BELONGTO.DEPT_TYPE,DEPT_UNID);
收集统计信息:
sp_index_stat_init('UCAP_PRICE','IDX_UCAP_DEPT_TO_TYPE');
看看执行计划:
可惜不是最优的计划,但是这个计划在并发的情况下速度不会慢的,代价也很小。在目前的版本里面这个计划算是最优的。
根据上面的计划,走 NEST LOOPINDEX JOIN2 的话,按照下面的索引顺序建索引是否会好点呢?
create index IDX_UCAP_DEPT_TO_TYPE on ucap_price.UCAP_DEPT(DEPT_TYPE,DEPT_BELONGTO,DEPT_UNID);
收集统计信息:
sp_index_stat_init('UCAP_PRICE','IDX_UCAP_DEPT_TO_TYPE');
此时的执行计划:
可以看到在第 8 行,一个走的是 NEST LOOP INDEXJOIN2 一个走的是 HASH2 INNER JOIN 我们知道,走 hash 的话对内存等要求比较高,并发下面占用内存比较多。所以这个 a 的索引顺序比较合适。因为目前系统刚上线数据量比较小,后期数据量大的话效果会更明显。并且但从计划上面也可以看出,就目前的数据量来看,a 的索引顺序比b的代价要小,并且实际执行的时间比 b 的也快1被以上(K1 环境)。
上面的 SQL 在 Oracle 中测试了下,发现 Oracle 中索引的顺序没有影响,两种索引计划一样:
文章
阅读量
获赞