【条件】:

      1)表名 tb_process

      2)索引有 index_mobile,index_create_date  ,无组合索引

      3)数据量 2898万

      4) select  count(*)  from tb_process  where    create_date>= '2017-11-17 00:00:00' and create_date<= '2017-12-10 00:00:00'  and is_deleted =0 and mobile  in ( ?,?,?)

【问题】:

       使用create_date, mobile 同时作为查询条件时(jdbc连接池),查询速度非常慢(70s),在某个时间点偶尔一次会非常块(2s),同时会存在如下情况:

     1) explain 解释器显示走到了两个索引分别为: index_mobile,index_create_date 

     2) 实际查询效率,远不如走到单个索引效率  index_mobile索引 5s, index_create_date 3s

 

【原因】:

     explain 解释器从语法上会走到2个索引,但实际上当实际执行查询的时,即使有多个单列索引,MySQL只能使用一个索引,当有2个单列的索引,MySQL会试图选择一个限制最严格的索引,大量数据时也有可能会索引失效 ;

【排查方法】:调整查询条件,对比走单列索引耗时情况,以确定索引是否生效。

【解决方案】:强制使用性能最高的索引 或 建立多列的组合索引

条件索引耗时单位(秒)
create_date, mobile 强制索引index_create_date 2s
create_date, mobile 强制索引
index_mobile
22s
create_date, mobile 默认索引30s
mobile,create_date 默认索引36s
   

             以上为Navicat Premium客户端与jdbc连接池查询结果


【强制索引语法】:

   select * from table_name [ force index( idx_name ) ]  where condition


其他:

        USE INDEX ——MySQ 去参考的索引列表,就可以让 MySQL 不再考虑其他可用的索引。
       IGNORE INDEX——MySQL 忽略一个或者多个索引。
       FORCE INDEX—— 强制 MySQL 使用一个特定的索引。


Logo

更多推荐