您现在的位置: 365建站网 > 365文章 > MYSQL解决where in过多值索引不生效的解决方法(强制索引force index)

MYSQL解决where in过多值索引不生效的解决方法(强制索引force index)

文章来源:365jz.com     点击数:3130    更新时间:2022-04-29 17:30   参与评论

      用户反映MYSQL中某个表前端查询很慢,前端显示需要10多秒,于是我方把监控到的SQL语句执行查询,结果如下:

</>code

  1. SELECT
  2.  sum(num)FROM
  3.  `user_coin_log` force index (ix_5)WHERE
  4.  `create_time` >= 1584892800AND `create_time` < 1584979200AND `source` = 5AND `uid` IN (
  5.  23,
  6.  24,
  7.  26,
  8.  29,
  9.  32,
  10.  33,
  11.  38,
  12.  42,
  13.  52,
  14.  59,
  15.  68,
  16.  69,
  17.  71,
  18.  72,
  19.  73,
  20.  79,
  21.  83,
  22.  85,
  23.  108,
  24.  111,
  25.  139,
  26.  229,
  27.  261,
  28.  280,
  29.  281,
  30.  283,
  31.  296,
  32.  298,
  33.  308,
  34.  401,
  35.  423,
  36.  490,
  37.  523,
  38.  650,
  39.  653,
  40.  776,
  41.  903,
  42.  913,
  43.  966,
  44.  997,
  45.  1030,
  46.  1381,
  47.  1704,
  48.  1809,
  49.  1922,
  50.  1943,
  51.  2011,
  52.  2037,
  53.  2146,
  54.  2459,
  55.  2757,
  56.  3055,
  57.  3087,
  58.  3098,
  59.  3280,
  60.  3315,
  61.  3427,
  62.  3701,
  63.  5132,
  64.  5625,
  65.  6646,
  66.  7628,
  67.  8040,
  68.  8464,
  69.  23304)AND `coin_id` = 1LIMIT 1

在这里插入图片描述
       执行时间需要5.466S,于是分析这个SQL语句,从语句的结构来看,where条件有时间create_time,uid等条件过滤,直觉应该不至于如此慢,而且该表上是有一个索引ix_5,同时覆盖了create_time,uid,source,coin_id,num等列的,但此SQL执行计划并没有走这个索引,而是走了一个单列索引UID不太合理,于是经过多方面排查与尝试,如果把这个UID条件去掉,或把UID里面的列表值大量减少,这个时候会走ix_5索引,甚至如果让uid in一个临时表(把所有的uid值建成1个临时表),这个时候也会走ix_5索引,执行时间会在0.8s内!
       顺着这个方向继续排查,发现网上有不少类似的案例,其现象都是:in后面如有太多值,MYSQL会认为全面扫描会更有效率,看来这一点还是不够oracle的优化器智能啊!于是尝试采用强制索引的方案来解决,具体加上(force index (ix_5))后,语句变成:

</>code

  1. SELECT
  2.  sum(num)FROM
  3.  `user_coin_log` force index (ix_5) WHERE
  4.  `create_time` >= 1584892800AND `create_time` < 1584979200AND `source` = 5AND `uid` IN (
  5.  23,
  6.  24,
  7.  26,
  8.  29,
  9.  32,
  10.  33,
  11.  38,
  12.  42,
  13.  52,
  14.  59,
  15.  68,
  16.  69,
  17.  71,
  18.  72,
  19.  73,
  20.  79,
  21.  83,
  22.  85,
  23.  108,
  24.  111,
  25.  139,
  26.  229,
  27.  261,
  28.  280,
  29.  281,
  30.  283,
  31.  296,
  32.  298,
  33.  308,
  34.  401,
  35.  423,
  36.  490,
  37.  523,
  38.  650,
  39.  653,
  40.  776,
  41.  903,
  42.  913,
  43.  966,
  44.  997,
  45.  1030,
  46.  1381,
  47.  1704,
  48.  1809,
  49.  1922,
  50.  1943,
  51.  2011,
  52.  2037,
  53.  2146,
  54.  2459,
  55.  2757,
  56.  3055,
  57.  3087,
  58.  3098,
  59.  3280,
  60.  3315,
  61.  3427,
  62.  3701,
  63.  5132,
  64.  5625,
  65.  6646,
  66.  7628,
  67.  8040,
  68.  8464,
  69.  23304) AND `coin_id` = 1LIMIT 1

再次执行:
在这里插入图片描述
加上HINT后,SQL效率得到了10倍以上的提升,由原来的5.4S下降到0.3S,性能提升效果显著!

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛

发表评论 (3130人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
昵称:
最新评论
------分隔线----------------------------

快速入口

· 365软件
· 杰创官网
· 建站工具
· 网站大全

其它栏目

· 建站教程
· 365学习

业务咨询

· 技术支持
· 服务时间:9:00-18:00
365建站网二维码

Powered by 365建站网 RSS地图 HTML地图

copyright © 2013-2024 版权所有 鄂ICP备17013400号