mysql慢sql优化实战:in order by优化处理

news2024/11/24 15:48:41

背景

     线上查询慢的问题日益突出,专门写一个帖子记录一下处理过程,会定期更新优化处理方案
     套餐余量统计查询菜单,数据库查询时间一分钟五十秒,优化之后耗时109毫秒,性能提升很大.所有时间统计均以数据库层面进行统计.用户使用层面因为有数据传输、带宽、业务逻辑处理等因素查询时间会更长,只看数据库查询层面可以排除其他因素影响。
     待优化sql:

SELECT manage_staff_card.id,manage_staff_card.card_no, manage_staff_card.status, manage_staff_card.rest_count,
        manage_staff_card.card_type, manage_card.time_type , manage_staff_card.single_price
        FROM manage_staff_card 
        LEFT JOIN `manage_staff` ON manage_staff.`login` = manage_staff_card.`login` LEFT JOIN `manage_card`
        ON manage_card.`id` = manage_staff_card.`card_id` LEFT JOIN `manage_studio` ON manage_studio.`id` = manage_staff_card.`studio_id`
        LEFT JOIN `manage_staff_studio` ON manage_staff_studio.`login` = manage_staff_card.`login` AND manage_staff_studio.`studio_id` = manage_staff_card.`studio_id`
        LEFT JOIN `manage_user_studio` ON manage_user_studio.`login` = manage_staff_studio.`teacher_login` AND manage_staff_studio.`studio_id` = manage_user_studio.`studio_id`
        LEFT JOIN `manage_contract_card` ON manage_contract_card.`staff_card_id` = manage_staff_card.`id` 
        LEFT JOIN `manage_contract` ON manage_contract.`contract_no` = manage_contract_card.`contract_no`
        WHERE manage_staff_card.status IN(8,5,15,20) ORDER BY manage_staff_card.create_time DESC

    执行计划如下:
在这里插入图片描述
    根据优化经验,一般type为all、index都需要进行优化,最少保证到ref。先从下面开始看
    manage_contract中type为all,看下sql中manage_contract用作表连接,直接将contract_no字段添加索引:

ALTER  TABLE  manage_contract  ADD  INDEX  idx_card_no (contract_no);

    添加成功后查询索引:

SHOW INDEX FROM manage_contract

    重新explain:
在这里插入图片描述
    type变更为ref,预估扫描的行数变更为1.继续看往下看.
    manage_contract_card中type为all,看sql中manage_contract_card中staff_card_id、contract_no在查询中都体现,是不是两个都需要创建索引呢,答案是不需要,只需要对staff_card_id进行创建索引。自己测试过两个都添加索引最终的执行计划type会变更为index,index和all都算是全表扫描,因为添加上contract_no之后再和manage_contract联查时需要按照contract_no全部扫描一遍manage_contract_card,实际上执行上一步的时候已经根据staff_card_id将符合要求的manage_contract_card查询出来,所有这里对于manage_contract_card只添加一个staff_card_id即可。
    添加索引

ALTER  TABLE  manage_contract_card  ADD  INDEX  idx_staff_card_id (staff_card_id);

    添加成功后查询索引:

SHOW INDEX FROM manage_contract_card  

    重新explain:
在这里插入图片描述
    type变更为ref,预估扫描的行数变更为1.继续看往下看.
    manage_staff_card放到最后讲是因为这个会比较特殊。首先看排序,排序会导致索引失效,对按照创建时间排序的业务来讲,可以使用主键id进行倒序可以进行替换实现业务逻辑,另外不需要单独根据创建时间字段添加索引,直接使用主键索引。毕竟不是索引越多越好。修改sql之后重新explain:
在这里插入图片描述
    type变更为index,由于是id主键排序,所以基本上开始全表扫描.下面在看manage_staff_card中status.直接给status添加索引:

ALTER  TABLE  manage_staff_card  ADD  INDEX  idx_status (STATUS); 

    重新执行explain发现索引是不生效的,是因为in会导致索引失效,继续往下看.
在这里插入图片描述

    关于in的业务场景实际开发中还是比较多的,i查阅资料总结了一下in常用的优化方案:

1.使用JOIN替代IN查询。如果条件中的IN查询可以转换为JOIN查询,有可能会对性能有一定提升
2.IN查询中的值列表存储到临时表中,然后使用JOIN查询
3.exists能否替代
注意:对于in中全部是参数值的,使用exist代替in无效

    以上各种优化方案都试过,对于本场景中in为参数值的情况,上面都不适用,这里的处理方式是对于manage_staff_card 中的status索引进行强制执行,manage_staff_card后面添加FORCE INDEX(idx_status).重新执行explain:
在这里插入图片描述
    会发现type类型变更为range.重新执行sql后耗时:0.109秒
    最终优化后的sql:

EXPLAIN  SELECT manage_staff_card.id,manage_staff_card.card_no, manage_staff_card.status, manage_staff_card.rest_count,
        manage_staff_card.card_type, manage_staff.real_name ,  manage_card.time_type , manage_staff_card.single_price
        FROM manage_staff_card  FORCE INDEX(idx_status)
        LEFT JOIN `manage_staff` ON manage_staff.`login` = manage_staff_card.`login` LEFT JOIN `manage_card`
        ON manage_card.`id` = manage_staff_card.`card_id` LEFT JOIN `manage_studio` ON manage_studio.`id` = manage_staff_card.`studio_id`
        LEFT JOIN `manage_staff_studio` ON manage_staff_studio.`login` = manage_staff_card.`login` AND manage_staff_studio.`studio_id` = manage_staff_card.`studio_id`
        LEFT JOIN `manage_user_studio` ON manage_user_studio.`login` = manage_staff_studio.`teacher_login` AND manage_staff_studio.`studio_id` = manage_user_studio.`studio_id`
        LEFT JOIN `manage_contract_card` ON manage_contract_card.`staff_card_id` = manage_staff_card.`id` 
        LEFT JOIN `manage_contract` ON manage_contract.`contract_no` = manage_contract_card.`contract_no`
        WHERE manage_staff_card.status IN(8,5,15,20) ORDER BY manage_staff_card.id DESC

    总结:
    1.left join中添加索引一般是从left join后面的表中的连接字段进行添加索引,而不是只要left join表的查询条件中有的字段都添加索引.
    2.order by排序时可以使用主键排序替换字符串排序;
    3.in的常用优化处理方式,上面已补充,这里不再重复;
    以上sql优化的处理过程,如果看到这里感觉有所帮助欢迎点赞或收藏!下面是最近参与的一个匿名社交类的微信小程序,有兴趣的可以看下
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

只要7分钟,教你从0-1搭建BI系统,这份大佬整理的指南免费送!

在BI行业干了快十年了,做过制造业供应链的BI项目,也跟过零售电商、房地产、银行的BI建设,经常有朋友咨询关于BI建设的内容,今天总结了一套BI项目建设指南,直接分享给大家,觉得不错记得点赞收藏。 通常情况…

实战【金融评分卡】

金融评分卡 网站:百融、同盾 1.导入 信贷评分卡是一种用于评估个人或企业申请贷款的工具,就像-个评分表-样。我们可以把它看作是银行或金融机构用来判断某人是否有资格获得贷款的一-种方式。 想象一下,你是一个银行家,有很多人向你申请贷款,比如个人贷…

cas单点登录-服务端部署

一.需求描述 公司开发系统越来越多,每个系统都有自己的登录认证流程,给用户很繁琐的体验,统一认证单点登录迫在眉睫 二.流程图 三.本地运行cas服务端 1.拉取cas服务端代码,切换到对应分支(我使用的是6.4.x&#xff…

proxmox7.4 安装后配置

关于proxmox7安装和配置的博文,倒是不少。可惜鱼龙混杂,踩了不少坑,如今实践成功后,做一分享。 proxmox7.4安装(与安装linux系统类似) 1.去官网https://proxmox.com/en/downloads 下载安装镜像,注意: 下…

iTOP-3588开发板Android12源码定制开发uboot开发

uboot 开发-Uboot 源码是 v2017.09 版本。目前在该平台上已经支持 RK 所有主流在售芯片。支持 的功能主要有:  支持 RK Android 固件启动;  支持 Android AOSP 固件启动;  支持 Linux Distro 固件启动;  支持 Rockchip miniloader 和 SPL/TPL 两种 Pre-loader 引导…

对比才知差距!海尔“精华洗”用实验告诉用户

《怪诞关系学》一书中讲到,人生来会与他人做比较,对比是天性,竞争是必然。用高深点的话讲,人是通过对比身边的事物和同类来定位自身的,只有对比才知道差距有多大。“仰观宇宙之大,俯察品类之盛”&#xff0…

Python如何批量合并70个doc和docx文件

目录 一、问题的提出 二、算法分析 三、代码展示 四、注意事项 有一位朋友发来70多个数名命名的doc和docx文件,问我有没有vba代码,可以把这些文件按照数字大小的顺序合并。我试着用了chatgpt,搞了一串vba代码行不通,于时我就找…

【PyQt5】(01)PyQt的详细介绍

文章目录 前言一、PyQt的前世今生1.1 PyQt6、PyQt5和PyQt41.2 商业版和开源版1.3 支持的操作系统 二、 PyQt的优点三、PyQt的应用场景总结 前言 PyQt是使用Python语言编写的QT库的界面工具包。QT是一个跨平台的C应用程序开发框架,可以用于创建高性能、高可靠性、图形…

高频面试八股文用法篇(六) 说说反射及其作用

目录 什么是反射? 反射的作用 反射的优缺点 反射的用途 什么是反射? 动态语言。 当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。Java 并不是动态语言,但是它却又一个非常突出的动态相关的机制&am…

Permission denied, please try again.

如果你是容器或者二进制安装启动的gitlab,在克隆代码一直有这样的问题 正克隆到 h5... git192.168.0s password: Permission denied, please try again. 服务ipgit 192.168.40.15 gitlab192.168.40.17 1、 docker run -d --name gitlab -p 80:80 -p 224:22 -p 4…

基于springboot的在线学习平台

源码获取,V:qq2056908377 采用技术 项目整体采用传统的B/S架构和MVC设计模式,开发语言选用JavaHTMLJavascript,技术上采用SpringBoot、Mybatis等开发框架,数据库采用MySQL 5.7。 功能介绍 平台分为用户端和管理两个系…

1.8 基于Java配置方式使用Spring MVC

一、基于Java配置方式使用Spring MVC 实现步骤 1、创建Maven项目 Maven项目 - SpringMvcDemo02 2、添加相关依赖 在pom.xml文件里添加相关依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/…

chatgpt赋能python:如何用Python创建一个成功的项目

如何用Python创建一个成功的项目 无论是初学者还是有经验的开发者&#xff0c;Python语言的丰富生态系统和易于使用的语法使得它在项目开发领域中成为了一种非常流行的选择。但是&#xff0c;要构建一个好的Python项目需要很多工作&#xff0c;需要一些经验和技巧。在这篇文章…

LeetCode_二叉树_BFS_中等_117.填充每个节点的下一个右侧节点指针 II

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给定一个二叉树&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; }填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将 …

数据共享传输:台式机和笔记本同步文件!

为什么要在台式机和笔记本同步文件&#xff1f; “我想在台式机和笔记本同步文件。因为我工作时使用笔记本&#xff0c;在家里使用安装了Windows 10系统的台式机&#xff0c;我想要在笔记本和台式机之间同步应用程序、游戏、文档等。有没有一种可以在台式机和笔记本同步文件的…

11 【组件通信】

1.props 适用于的场景:父子组件通信 注意事项: 如果父组件给子组件传递数据(函数):本质其实是子组件给父组件传递数据 如果父组件给子组件传递数据(非函数):本质就是父组件给子组件传递数据 书写方式:3种 [‘todos’],{type:Array},{type:Array,default:[]} 特殊情况&am…

为何要将行驶证转为Excel?在线怎么操作?需要注意些什么?

一、为何要将行驶证转为excel表格&#xff1f;有何好处&#xff1f; 将行驶证转为Excel一般是为了方便信息的整理和管理。将行驶证上的信息录入Excel表格中&#xff0c;可以实现快速搜索、排序和筛选等功能&#xff0c;避免了手动整理信息的繁琐和容易出错的问题。此外&#xf…

ChatGPT 时代,程序员的生存之道 | 人工智能 AI

ChatGPT 近期炙手可热&#xff0c;仿佛没有什么问题是它不能解决的。出于对 ChatGPT 的好奇&#xff0c;我们决定探索下它对于前端开发人员来讲&#xff0c;是作为辅助工具多一些&#xff0c;还是主力工具更多一些&#xff1f; 2D 能力测试 我们就挑选一个著名的递归回溯问题—…

MySQL的知识点整理(学习笔记)

目录 一、认识数据库 1. 什么是数据库 2. 数据库类型 3. 常见的数据库管理系统 4. MySQL介绍 5. MySQL的安装&管理工具的安装 6. SQL概述 7. 在DOS系统中操作MySQL 8. MySql常用命令 二、操作数据库 1、使用navicat创建数据库 2、备份和还原数据库 3、MySQL数据…

医疗文本智能标注工具接连落地,景联文科技助力“GPT+健康医疗”稳步前行

随着医疗技术的飞速发展和普及&#xff0c;医疗数据量日益庞大&#xff0c;医疗数据的处理成为了一个极为重要的问题。医疗数据中包含着众多的病历记录、化验报告、影像资料等&#xff0c;这些数据需要专业人员运用专业的知识进行处理。目前&#xff0c;很多医院和相关研究机构…