mysql表关联的索引命中失败和由此带来的思考

###问题描述
最近翻了慢查询日志,大多数都是备份,夜晚的临时查询表生成,但是偶尔有几句是早年间留下的legend code留下的错误.有几个显示的问题
目前看来对于关联大表都要小心谨慎,尤其是关联条件的使用,本次出现的问题就在于join的on条件下过长导致的
虽然使用慢查询在生产环境中可以看到
LEFT JOIN orders o ON u.user_id = o.user_id and o.chain_id = ‘158’ and o.create_date > ‘2022-01-01’ and o.create_date < ‘2022-02-01’

# Query_time: 12.742334 Lock_time: 0.000586 Rows_sent: 4 >\Rows_examined: 17050666
SET timestamp=1642946504;

LEFT JOIN orders o ON u.user_id = o.user_id and o.chain_id = ‘158’ and o.create_date > ‘2022-01-01’ and o.create_date < ‘2022-02-01’

###问题分析
使用虽然explain可以看到索引没有命中,普通的索引都没有命中,给其他地方优化的联合索引也没命中(这和联合索引的左命中原理有关)

主要的原因在于orders表是大表,在关联后的命中索引失败后,他的产生的性能损失就很大.所以要想办法用其他方式命中索引.这里面涉及到很底层的mysql优化问题,我们普通的开发者是很难花时间去学习的.在这里我首先是查找了google,查了range checked for each record
,然后一个stack讨论很有意思(搜索引擎的使用是一个人的重要技能,马前卒有一句话很有意思,大多数人而言他们百度都没有使用的透彻)
https://stackoverflow.com/questions/54459775/mysql-join-between-range-checked-for-each-record-index-map-0x7

最后给的优化思路是吧on里面根据条件和订单表的索引的其他两个条件拆分出来,这样表关联中命中了user_id和chain_id
而 create_data放到了where语句中.虽然如此还要额外在写一句查询来匹配空出的数据.但是时间也拉到了正常的水平内.

思考

在mysql的慢查询中,出现过的问题要小心大表的,尤其是出现表关联后,虽然我们知道不同版本下的mysql优化也在不断地进步,很多早年间写的慢语句,建议都已经不在符合新版本.但是有几个核心的建议还是始终符合的.

  • 大表的关联和查询都要小心,是否命中索引都要小心,一旦索引命中失败,带来的成本将是恐怖的.使用子查询提前命中索引后查出条目放入临时表.使用缓存把之前语句提前提取出来,使用多个短查询代替表关联.都是很好用的做法
  • 对数量级要有敏感度,对于几千条表下,ALL(没命中索引)其实也是无所谓的.而达到几十万后,索引命中失败带来的压力就不容忽视.类似的类似bool类型索引实际上对于大表下他的优势就没有那么大了,即便命中了,带来的提升也没有那么大.再比如使用表关联后,一旦索引命中失败,那么即便是两个中等大小的表,他的乘积也会变成大表,这时候就要小心优化了.

mysql表关联的索引命中失败 range checked for each record相关推荐

  1. mysql 添加表索引_如何向MySQL表中添加索引?

    如何向MySQL表中添加索引? 我有一个非常大的MySQL表,包含大约15万行数据.目前,当我试着运行SELECT * FROM table WHERE id = '1'; 代码运行良好,因为ID字段 ...

  2. Mysql多表关联不走索引的原因

    刚入职第一天,有个大佬写了一个统计函数count(*)需要对两张表a,b做统计.咋一看挺简单的,可是表a有1000万条数据,表b有300万条数据.使用LEFT JOIN进行查询.结果,一直查询不出来, ...

  3. thinkphp通过模型查询mysql_thinkPHP视图模型详解,把mysql表关联简单化!

    学过sql的人都知道有表左关联,右关联,但是sql语句要写很多,非常容易出错,而ThinkPHP的视图模型则简单化很多了.还发现个问题,貌似ThinkPHP手册写的很多东西都不是很完善,很多人看了都不 ...

  4. php mysql 表关联,mysql的多表关联_MySQL

    bitsCN.com mysql的多表关联 数据库中经常要用到多个表的关联.mysql的关联主要包括inner join,left join,right join三种,下面分别加以介绍,并举例说明. ...

  5. MySQL表关联及关联查询

    主键 表中的一个字段,该字段的值是每一行数据的唯一标识. 默认情况下,每张表都要有一个主键,也只能有一个主键. 主键生成策略:代理主键,与业务无关的字段,仅仅是用来标识一行数据,一般定义为int类型, ...

  6. mysql表关联_MySQL表关联的几种常用方式

    工作中我们经常会使用表与表关联来查询数据,如果对join 不熟悉,可能会得到我们不想要的节过,这里就来介绍下join的几种常用方法: 建表及插入数据, CREATE TABLE school ( sc ...

  7. mysql内联表格使用索引_【求助】MYSQL表关联内联视图不走索引问题??诡异啊...

    首先声明: FACT_DATE_SALES_CI_INDEX 的DAY,DIM_ORG建有复合索引,同时FACT_DATE_SALES_FACT_DATE_SALES_F1表的RETAIL_SALES ...

  8. mysql表关联查询都有什么方式_所有关联表查询方式

    前言 想象场景:小白初入职场,看到很多数据库的代码发现都不清楚,急哭小白了,急急忙忙的去百度,收集到的资料很多,也很迷,乱七八糟的都是 虫虫:为了方便小白 虫虫把关联表的查询方式总结了 关联查询种类 ...

  9. mysql表关联字段长度不一样_mysql优化sql案例,5.6版本的致命点之两表关联的字段类型相同的重要性...

    时间大大的缩短: 但是这个还不是最优化的:后面又发现关联表那边有这样的一个语句: FROM np_order n left join web114_order_ledger wol on n.orde ...

最新文章

  1. 通过Attached Property给控件绑定Command(二)
  2. js获取上传文件内容
  3. mybatis-MyBatis-Plus
  4. 警惕开源代码库中的安全隐患
  5. 单片机检测220V交流电通断电路
  6. Struts 2框架创建的第一个项目
  7. bookkeeper源码解析
  8. Django登录验证——原生表单验证
  9. 通过配置hosts.allow和hosts.deny文件允许或禁止ssh或telnet操作
  10. makefile phony
  11. 【GoLang】GO语言系列--002.GO语言基础
  12. idea的tomcat实现热部署遇到的问题
  13. Python库(x)纯小学生(我)自制
  14. 苹果电脑安装计算机一级,偷天换日!让普通笔记本安装苹果系统
  15. c/c++实现简单的贪吃蛇可视化游戏
  16. 计算机硬件检测与维修理论试题,计算机硬件检测与维修试题10.doc
  17. DB buffer bussy wait 分析一例
  18. iOS 二维码生成 (Swift代码)
  19. 独立同分布(Independently and Identically Distributed, iid)
  20. 【算法练习】数据结构/图论 poj4084:拓扑排序

热门文章

  1. 手动脱简单的虚拟机壳(themida)
  2. 常见协议及对应的因特网协议栈
  3. (离散数学)排列与组合
  4. 进入Sic-Hub的办法
  5. 对比欧氏距离与余弦相似度
  6. 基于SSM医药后台管理系统
  7. 知识补充2:Elasticsearch的基本使用(Windows+Python)
  8. 双屏切换单屏,之前在另一显示器显示的软件窗口现无法显示解决方法
  9. 光速搭建centos7虚拟机
  10. 论如何优雅的用Vue从前台导入excel(并处理单元格合并问题)