美文网首页MySQL(总)MySQL索引
关于索引不走or的思考(完结)

关于索引不走or的思考(完结)

作者: 飞翔的Tallgeese | 来源:发表于2018-03-15 15:59 被阅读1次

原语句(金融云trade库)

SELECT

    sum( amount )

FROM

    tra_trade

WHERE

    STATUS = 'success'

    AND partner_id != '*********************00008'

    AND partner_id != '*********************00074'

    AND partner_id != '*********************00009'

    AND date_format( update_time, '%y' ) = date_format( now( ), '%y' );

存在问题

1.存在!=,而且是3个

2.存在对时间函数的隐式转换

分析

1.date_format存在函数的隐式转换,无法优化

2.status列和partner_id列的选择性分别只有0.0000003和0.0001

3.连续3个!=,相当于not in

结论

对于索引列,及时创建联合索引也不会走;

实际测试也是如此;

所以在前面3.13的记录里面,认为无法对其进行优化。

转折

忽略了查询列,查询列的选择性达到了0.11

创建索引列和查询列的联合索引

ALTER TABLE `trade`.`tra_trade` ADD INDEX idx_status_partnerid_amount (`status`, `partner_id`, `amount`);

通过执行计划获知扫描行由24W行变成了4W行!

延伸

索引准则有一句:

不等空值还有or,索引失效要少用

这里很明显存在不等,反过来如果是3个等于的话,那么很明显也会存在or,但是索引确没有失效!

首先需要明白这句话对应的条件

tra_trade表是trade库中一张行数为24W的表,其中id,gid,trade_no选择性为1,partner_id选择性为0.0001

create table tra_trade_test as select id,gid,merchant_order_no,trade_no,amount,seller_user_id,payer_user_id,trade_name,status,partner_id

from tra_trade;

create index idx_test_0 on tra_trade_test(gid);

create index idx_test_1 on tra_trade_test(trade_no);

create index idx_test_2 on tra_trade_test(partner_id);

语句1

explain

select * from tra_trade_test where id>5000 and gid in ('*********************113e48fc','*********************113e48fe','*********************9b795a0','*********************113e4909');

毫无意外的走索引,即使索引列的2个条件都是范围查询,扫描行数仅仅为4行

删除gid索引

explain

select * from tra_trade_test where id>5000 and gid in ('*********************113e48fc','*********************113e48fe','*********************9b795a0','*********************113e4909');

仍然走索引,扫描行数暴增到12W,key_len只有8,说明只有id走了索引,此时虽然gid上面没有了索引,但走(id的)索引代价仍然比全表要小

语句2

将之前删掉的索引补回去

create index idx_test_0 on tra_trade_test(gid);

explain

select * from tra_trade_test where id>5000 or gid in ('*********************113e48fc','*********************113e48fe','*********************9b795a0','*********************113e4909')

执行计划中的type类型是index_merge,扫描行数为12W,index_merge的意思是索引执行了合并,这是因为我们此时应该把id和gid组成联合索引,这样效率会更高;但此时也没有走全表

删除gid索引

explain

select * from tra_trade_test where id>5000 or gid in ('*********************113e48fc','*********************113e48fe','*********************9b795a0','*********************113e4909')

毫无疑问的走全表了(所以可以看出,准则适用的其实是这里

语句3

将之前删掉的索引补回去

create index idx_test_0 on tra_trade_test(gid);

explain

select * from tra_trade_test

where gid = '*********************113e48fc'

or gid = '*********************113e48fe'

or gid = '*********************9b795a0'

or gid = '*********************113e4909';

该语句等效于

explain

select * from tra_trade_test where gid in ('*********************113e48fc','*********************113e48fe','*********************9b795a0','*********************113e4909');

毫无疑问的走了范围索引(可以看出,单列上存在索引,无论是否存在or,都会走索引,准则所说的情况并非这类语句

关于not in(!=)

语句4

explain

select gid from tra_trade_test

where gid != '*********************113e48fc'

and gid != '*********************113e48fe'

and gid != '*********************9b795a0'

and gid != '*********************113e4909';

explain

select id from tra_trade_test

where gid != '*********************113e48fc'

and gid != '*********************113e48fe'

and gid != '*********************9b795a0'

and gid != '*********************113e4909';

上述两条都走了索引

explain

select trade_no from tra_trade_test

where gid != '*********************113e48fc'

and gid != '*********************113e48fe'

and gid != '*********************9b795a0'

and gid != '*********************113e4909';

trade_no列上也建有索引,而且选择性为1,但是这条语句走了全表;

相关文章

  • 关于索引不走or的思考(完结)

    原语句(金融云trade库) SELECT sum( amount ) FROM tra_trade WHERE ...

  • MySQL正确使用索引

    需要解决的问题 知道sql为什么会走索引? 为什么有些sql不走索引? sql会走那些索引,为什么会这么走? In...

  • MySQL in 走不走索引?

    1. 连表查询或采用临时表会走索引 参考:解决MySQL中IN子查询会导致无法使用索引问题 2. 如果 in ...

  • Pandas数据操作

    Pandas数据操作 Series索引 行索引 切片索引 不连续索引 布尔索引 DataFrame索引 列索引 不...

  • 关于mysql的索引

    我们首先创建一个表并且创建索引 我们通过这些测试 可以看出包含name的走name_age_sex的索引 如果不包...

  • MySQL索引知多少

    mysql索引 总结关于mysql的索引,查询优化,SQL技巧等 1 索引类型 B-Tree索引 Hash索引 ...

  • 关于代码走查的思考

    昨天公司进行了团队评比,其中有一项就是代码走查。目前有两种方式,一种是通过会议进行抽查,一次性多人参加;另一种是通...

  • 面试必备的索引优化

    关于索引,分为以下几点来讲解(技术文): 索引的概述(什么是索引,索引的优缺点) 索引的基本使用(创建索引) 索引...

  • 图解 MySQL 索引:B-树、B+树,终于搞清楚了

    看了很多关于索引的博客,讲的大同小异。但是始终没有让我明白关于索引的一些概念,如B-Tree索引,Hash索引,唯...

  • 图解 MySQL 索引:B-树、B 树,终于搞清楚了

    看了很多关于索引的博客,讲的大同小异。但是始终没有让我明白关于索引的一些概念,如B-Tree索引,Hash索引,唯...

网友评论

    本文标题:关于索引不走or的思考(完结)

    本文链接:https://www.haomeiwen.com/subject/dkphqftx.html