一次线上慢SQL调优分享

一个sql查询设置了联合索引,但是在查询的时候没有走联合索引,所以导致查询速度非常慢。因为MySQL查询优化器会自己判断这个查询所需要的代价,如果代价太大则不走联合索引,导致联合索引失效

用户的所有提交,都写入一张提交表,提交列表也是该表查询,表结构核心大致如下:

 CREATE TABLE `submit_topic` (
   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '提交ID',
   `topicset_id` int(11) NOT NULL COMMENT '题目集',
   `user_id` int(11) NOT NULL COMMENT '用户编号',
     /xxx
     //还包括 判题情况,分数等等
  
   PRIMARY KEY (`id`),
   KEY `topicsetIndex` (`topicset_id`,`user_id`) USING BTREE COMMENT '题目集用户索引'
 ) ENGINE=InnoDB AUTO_INCREMENT=57157 DEFAULT CHARSET=utf8mb4;

SQL的样子

注意了,以下是重点!!!!!

因为可以查询题目集 指定用户的提交列表(默认是查所有用户),所以我还加了一个联合索引,

  KEY `topicsetIndex` (`topicset_id`,`user_id`) USING BTREE COMMENT '题目集用户索引'

由于提交列表涉及到游标分页,所以默认查询最近提交列表 SQL大致是

 SELECT * FROM submit_topic as st
 //指定题目集ID
 where topicset_id = 34344   
 //根据主键ID游标分页查询
 and st.id > 12
 //因为ID递增,直接用ID排序
 ORDER BY st.id desc
 limit 20;

自从上线SQL就这样,查询效率也可观。随便一个题目集一查 ,使用explain如下:

正常情况100毫秒内解决,这里要提一嘴,Using filesort是表示用到了排序,是文件还是内存排序,要看数据量

说好的慢SQL呢?

继续定位,发现只有考试那几场题目集响应慢。于是将topicset_id换一个数作为查询条件,SQL还是之前的

 explain SELECT * FROM submit_topic as st
 -- //换了一个题目集ID
 where topicset_id = 42
 -- //根据主键ID游标分页查询
 and st.id > 123443
 -- //因为ID递增,直接用ID排序
 ORDER BY st.id desc
 limit 20;

explain结果一看吓死人:

扫描行数达到7万多,另外几个 直接扫了几十万😫😫😫😫,跑了5秒才出结果。

原因分析

Extra使用了Using where,索引走的是主键ID

所以SQL会先把id > 123443的都扫出来,然后利用索引自动排序,然后返回Server过滤出 topicset_id=42的记录, 好家伙这相当于全表扫描了啊!!!

正常情况是会走 topicset_id这个索引的呀(即使用到了排序)

  KEY `topicsetIndex` (`topicset_id`,`user_id`) USING BTREE COMMENT '题目集用户索引'

其实这个索引有个坑,就是 topicsset_id后面多了user_id,所以这个联合索引结合主键索引,类似于一个联合索引的效果,如下:

但是我们的SQL查询条件,没有用到user_id,这就导致主键ID索引不可用,所以 后面的排序 主键是用不到的。

如果一个topicset_id的提交数据太多,oder by id势必造成大量文件排序,这时 MySQL查询优化器认为排序代价太大,我干脆使用主键索引就避免排序,但而ID只有大于,使得扫描行数巨多,更要命的是要在如此多的数据里,Server层过滤出topicset_id = 42的记录。其次,由于Limit很小,优化器认为即使全表过滤也很快,然而事与愿违这几乎等于全表扫描!!!

问题解决

直接单独对 topicset_id设一个索引,根据MySQL索引下堆的原理,先通过topicset_id查询的主键是有序的,oder by不需要排序了。

最终SQL如下:

Using index Condition 表示索引下堆,索引下堆见五分钟搞懂MySQL索引下推-CSDN博客  因为topicset_id选出来的 id是有序的,我们直接在存储引擎层过滤掉了数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/478248.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

面试题小结

一、什么是虚拟dom 描述真实dom的js对象。 二、DOM操作——怎样添加、移除、移动、复制、创建和查找节点 (1)创建新节点 createDocumentFragment() //创建一个DOM片段 createElement() //创建一个具体的元素 createTextNode() //创建一个文本节…

二十、软考-系统架构设计师笔记-真题解析-2020年真题

软考-系统架构设计师-2020年上午选择题真题 考试时间 8:30 ~ 11:00 150分钟 1.按照我国著作权法的权利保护期,( )受到永久保护。 A.发表权 B.修改权 C.复制权 D.发行权 解析: 答案: 2.假设某计算机的字长为32位&a…

如何使用OpenHarmony从零开始构建一款智能音乐播放器全过程

介绍 随着鸿蒙操作系统的发布,开发者们迫不及待地想要探索鸿蒙应用的开发。本篇博客将以构建一款智能音乐播放器为例,带你一步步了解鸿蒙应用开发的技术要点和实践。我们将使用HarmonyOS的开发环境和MarkDown进行排版,方便你快速上手。 准备…

C++之继承详解

一.继承基础知识 继承定义: 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保 持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象 程序设…

JAVA多线程之线程池

文章目录 1. 线程池状态2. 线程池创建2.1 ThreadPoolExecutor2.2 newFixedThreadPool2.3 newCachedThreadPool2.4 newSingleThreadExecutor2.5 开发要求 3. 提交方法4. 关闭方法5. 任务调度5.1 Timer5.2 Scheduled5.2.1 构造方法5.2.2 schedule5.2.3 scheduleAtFixedRate5.2.4 …

计算机网络——物理层(宽带接入技术)

计算机网络——物理层(宽带接入技术) 什么是宽带有线带宽接入xDSLADSL 技术ADSL 的大部分组成 光纤同轴混合网(HFC 网)机顶盒与电缆调制解调器(set-top box) FTTx 技术光配线网 ODN (Optical Distribution …

最新,955神仙公司名单(非外企)

955 神仙公司名单(非外企) 往常爆料最多的 955 神仙公司名单通常都是集中在一线城市的外企。 例如下面这张最为流行的名单图: 最近牛客网上有同学整理出了非外企的版本,其中不乏一些耳熟能详的互联网产品。 随手把名单分享给大家。…

sonarqube使用指北(二)-如何启动一次完整的本地扫描

一、引言 上一篇文章之后 我们应该已经成功的部署了sonarqube程序,这一篇文章我们就来进行一次简单的本地扫描。 优点: 安全性:你可以在任何你信任的环境下执行扫描工作,而不是依赖外部安全能力即时反馈: 开发者可以在编写代码时获得即时反馈,了解其代码的质量和潜在问题…

机器学习----交叉熵(Cross Entropy)如何做损失函数

目录 一.概念引入 1.损失函数 2.均值平方差损失函数 3.交叉熵损失函数 3.1信息量 3.2信息熵 3.3相对熵 二.交叉熵损失函数的原理及推导过程 表达式 二分类 联立 取对数 补充 三.交叉熵函数的代码实现 一.概念引入 1.损失函数 损失函数是指一种将一个事件&#x…

SW工具下没有URDF

解决方案,下载

阿里云安装宝塔后面板打不开

前言 按理来说装个宝塔面板应该很轻松的,我却装了2天,真挺恼火的,网上搜的教程基本上解决不掉我的问题点,问了阿里云和宝塔客服,弄了将近2天,才找出问题出在哪里,在此记录一下问题的处理。 服…

十分钟快速入门 Python

本文以 Eric Matthes 的《Python编程:从入门到实践》为基础,以有一定其他语言经验的程序员视角,对书中内容提炼总结,化繁为简,将这本书的精髓融合成一篇10分钟能读完的文章。 读完本篇文章后,可对 Python …

【学习】软件测试行业未来的发展趋势预测

近年来,随着中国数字经济的蓬勃发展,软件测试行业也迎来了新的春天。从早期的手工测试到自动化测试,再到持续集成和持续交付,中国的软件测试行业经历了快速的发展和变革。各行各业均对软件测试提出了更高的要求,尤其在…

按摩师C语言

题干出现“接或不接”,“最优”&#xff0c;仔细一想&#xff0c;该用动态规划了。 #include<stdio.h> int max(int a,int b) {if(a>b)return a;elsereturn b; } int massage(int* nums,int numSize) {if(numSize 0)return 0;else if(numSize 1)return nums[0];els…

js 输出负数的个数,和所有正整数的平均值。

首先输入要输入的整数个数n&#xff0c;然后输入n个整数。输出为n个整数中负数的个数&#xff0c;和所有正整数的平均值&#xff0c;结果保留一位小数。 0即不是正整数&#xff0c;也不是负数&#xff0c;不计入计算。如果没有正数&#xff0c;则平均值为0。输入 11 1 2 3 4 5 …

zabbix6.4监控mysql数据库

目录 一、前提二、配置mysql数据库模板三、配置监控的mysql主机 一、前提 已经搭建好zabbix-server 在需要监控的mysql服务器上安装zabbix-agent2 上述安装步骤参考我的上篇文章&#xff1a;通过docker容器安装zabbix6.4.12图文详解&#xff08;监控服务器docker容器&#xf…

2016年认证杯SPSSPRO杯数学建模A题(第二阶段)洗衣机全过程文档及程序

2016年认证杯SPSSPRO杯数学建模 A题 洗衣机 原题再现&#xff1a; 洗衣机是普及率极高的家用电器&#xff0c;它给人们的生活带来了很大的方便。家用洗衣机从工作方式来看&#xff0c;有波轮式、滚筒式、搅拌式等若干种类。在此基础上&#xff0c;各厂商也推出了多种具体方案…

二、Web3 学习(区块链)

区块链基础知识 一、基础知识1. 区块链可以做什么&#xff1f;2. 区块链的三个特点 二、区块链的类型概括1. PoW2. PoS3. 私有链和联盟链 三、智能合约1. 什么是智能合约2. 如何使用智能合约 四、困境1. 三难选择的基本要素2. 这真的是一个三难选择吗? 五、比特币1. 什么是比特…

2024年服装erp系统排名,都有哪些品牌?

随着数字经济时代的到来&#xff0c;传统的服装纺织行业正在经历深刻的变革。如何实现产业数字化升级&#xff0c;是众多服装纺织企业所面临的共同课题。当前&#xff0c;服装erp管理系统已经成为服装企业实现智能化转型的关键&#xff0c;通过将所有流程环节的数据进行统一的信…

C语言字符函数与字符串函数:编织文字的舞会之梦(下)

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 C语言知识 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 目录 七、strncpy的使用以及模拟实现 八、strncat的使用以及模拟实现 九、strncmp的使用以及模拟实现 十、strstr的使用以及模拟…