11小透明
#1
【 OB 4.2.1.6】
SQL:
SELECT
*
FROM
test
WHERE
ts = (
SELECT
max(ts)
FROM
test
WHERE
xx IN (
)
AND attribute_clues_type = ?
)
xx字段可能为t1/t2/t3
字段类型为:
t1
varchar(64) DEFAULT NULL
t2
varchar(64) DEFAULT NULL
t3
varchar(1024) DEFAULT NULL
有以下索引:
PRIMARY KEY (id
),
KEY I_t1
(t1
, ts
, attribute_clues_type
) BLOCK_SIZE 16384 LOCAL,
KEY I_t2
(t2
, ts
, attribute_clues_type
) BLOCK_SIZE 16384 LOCAL,
KEY I_t3
(t3
, ts
, attribute_clues_type
) BLOCK_SIZE 16384 LOCAL,
有两个问题:
1.当xx为t1/t2时返回很快,为毫秒级,换成t3的时候就很慢,变成了秒级
2.ocp平台提示没有最佳索引,这块有点疑惑,明明已经有联合索引了
1、c3字段比其他字段长很多,同一个索引页中存放的key更少,所以索引i_t3的高度可能会比其他两个高,而且这个例子中,对于t3 in()这里面的条件每个值都会在索引里面全部扫描一次,然后再通过attribute_clues_type过滤之后再对ts取max,所以t3 in的条件更多可能慢的更明显。
2、ocp提示的最佳索引是对的,因为新的索引的query range比原有的索引query range更优,比如条件为t3 in (1) and attribute_clues_type in (2),在原有索引中,底层索引扫描需要扫描(1, min, min, min)到(1,max, max, max)把这些数据读取来之后再通过attribute_clues_type过滤,而OCP推荐的索引只需要扫描(1,2,min, min)到(1,2,max,max)在索引底层扫描的范围更小,区别就是attribute_clues_type在前面可以起到筛选底层数据的作用。
PS:以后SQL性能可以带上sql的explain extended的执行计划,这样比较好分析和理解。
11小透明
#4
问题1.这里的高度指的是什么
问题2.所以联合索引,匹配的时候和字段顺序有很大关系是么。还以为三个字段都带上的话 引擎会自动优化这个
1、可以网上找找讲B+树的文章,讲这个的很多,我随便找了一篇可以参考下https://www.cnblogs.com/kungfupanda/p/12776700.html
2、是的,和顺序有关系的,主要还是和索引的底层结构有关,在这个SQL中,OCP给的索引执行效率会更多,原因就是上面讲到的query range。主要还是看业务,如果大多数SQL以t3和attribute_clues_type为条件,那可以考虑改造成(t3
,attribute_clues_type
,ts
),反之保持现状就好。
11小透明
#7
这个情况,我把t3的长度改成和t1\t2一样,但是还没起作用,是不是得把联合索引删了再建?
11小透明
#8
出现了个奇怪的现象,在用t3这个字段时,取max(ts)的话执行计划会扫全表。
直接取ts的话,是范围查
max(ts):
直接取ts:
那可能不是索引高度的问题,可以看下extended的计划吗
11小透明
#10
老师您好,这个问题已经解决了。
我理解问题是这样的:CBO判断走全表比走索引快,所以优化后走了全表,其实可能是统计信息出来问题导致的。
然后我手动刷了下统计信息,现在是可以了。
我不是社区的老师,也是一同在学习的ober而已,有版主标识
的才是社区的官方老师。