索引-00 不为人知的秘密

1、强制使用索引

EXPLAIN  SELECT
	sum(if(type = 1,amount,0)) - sum(if(type = 2,amount,0)) as amount
FROM
	integral_wallet_seq force index (cust_id_index,inte_name_index)
WHERE
	
  inte_name = 'USDT' and cust_id = '511f3aa1256243c4a9dbab84cb8f9a8e'

 

2、index_merge(mysql之前只能用一个索引)

 为什么会有index merge

我们的 where 中可能有多个条件(或者join)涉及到多个字段,它们之间进行 AND 或者 OR,那么此时就有可能会使用到 index merge 技术。index merge 技术如果简单的说,其实就是:对多个索引分别进行条件扫描,然后将它们各自的结果进行合并(intersect/union)。
 MySQL5.0之前,一个表一次只能使用一个索引,无法同时使用多个索引分别进行条件扫描。但是从5.1开始,引入了 index merge 优化技术,对同一个表可以使用多个索引分别进行条件扫描。

index merge: 同一个表的多个索引的范围扫描可以对结果进行合并,合并方式分为三种:union, intersection, 以及它们的组合(先内部intersect然后在外面union)。

官方文档给出了四个例子:



SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;

SELECT * FROM tbl_name WHERE (key1 = 10 OR key2 = 20) AND non_key=30;

SELECT * FROM t1, t2 WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%') AND t2.key1=t1.some_col;

SELECT * FROM t1, t2 WHERE t1.key1=1 AND (t2.key1=t1.some_col OR t2.key2=t1.some_col2);

index merge 算法根据合并算法的不同分成了三种:intersect, union, sort_union.

 

2. index merge 之 intersect

简单而言,index intersect merge就是多个索引条件扫描得到的结果进行交集运算。显然在多个索引提交之间是 AND 运算时,才会出现 index intersect merge. 下面两种where条件或者它们的组合时会进行 index intersect merge:
 1) 条件使用到复合索引中的所有字段或者左前缀字段(对单字段索引也适用)

key_part1=const1 AND key_part2=const2 ... AND key_partN=constN

 

2) 主键上的任何范围条件

SELECT * FROM innodb_table WHERE primary_key < 10 AND key_col1=20;

SELECT * FROM tbl_name WHERE (key1_part1=1 AND key1_part2=2) AND key2=2;
 上面只说到复合索引,但是其实单字段索引显然也是一样的。比如 select * from tab where key1=xx and key2 =xxx; 也是有可能进行index intersect merge的。另外上面两种情况的 AND 组合也一样可能会进行 index intersect merge.
 

3. index merge 之 union

简单而言,index uion merge就是多个索引条件扫描,对得到的结果进行并集运算,显然是多个条件之间进行的是 OR 运算。

下面几种类型的 where 条件,以及他们的组合可能会使用到 index union merge算法:

1) 条件使用到复合索引中的所有字段或者左前缀字段(对单字段索引也适用)

2) 主键上的任何范围条件

3) 任何符合 index intersect merge 的where条件;

上面三种 where 条件进行 OR 运算时,可能会使用 index union merge算法。

例子:
 

SELECT * FROM t1 WHERE key1=1 OR key2=2 OR key3=3;

SELECT * FROM innodb_table WHERE (key1=1 AND key2=2) OR (key3='foo' AND key4='bar') AND key5=5;
 

第一个例子,就是三个 单字段索引 进行 OR 运算,所以他们可能会使用 index union merge算法。

第二个例子,复杂一点。(key1=1 AND key2=2) 是符合 index intersect merge; (key3=’foo’ AND key4=’bar’) AND key5=5 也是符合index intersect merge,所以 二者之间进行 OR 运算,自然可能会使用 index union merge算法。
 

4. index merge 之 sort_union

.(多个条件扫描进行 OR 运算,但是不符合 index union merge算法的,此时可能会使用 sort_union算法)

官方文档给出了两个例子:

SELECT * FROM tbl_name WHERE key_col1 < 10 OR key_col2 < 20;

SELECT * FROM tbl_name WHERE (key_col1 > 10 OR key_col2 = 20) AND nonkey_col=30;
 

但是显然:因为 key_col2 不是复合索引的第一个字段,对它进行 OR 运算,是不可能使用到索引的。所以这两个例子应该也是错误的,它们实际上并不会进行 index sort_union merge算法。

 

5. index merge的局限

(x AND y) OR z = (x OR z) AND (y OR z)

(x OR y) AND z = (x AND z) OR (y AND z)

如果我们的条件比较复杂,用到多个 and / or 条件运算,而MySQL没有使用最优的执行计划,那么可以使用上面的两个等式将条件进行转换一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值