Mysql 你还在一个字段一个索引吗

今天看到某系统的mysql在某时段存在thread_running线程数飙高触发告警,挤时间分析了该异常时间段的慢日志记录,并进行了sql优化

慢日志记录主要归为3个慢sql (编号1,2,3)

一、 1号sql原文

select * from `feeds` where `topics_id` > 0 and `audit_status` in (0, 1) and `enable_status` = 1 and `risk_status` in (0, 1) and (`visible` = 1 or `feeds`.`user_id` = 60548) and `feeds`.`deleted_at` is null order by `publish_time` desc limit 10 offset 0;

有limit 10 offset 0 限定最终结果的数据量,虽然走了索引,但是扫描近40万数据量,单并发执行耗时1.5秒~2秒,这能优化吗?

查看格式化后的sql,where的条件有点复杂,存在多个条件,可抽象出来抓可利用的组合索引,feeds(deleted_at,risk_status,enable_status,topics_id)

创建索引 idx2 feeds(deleted_at,risk_status,enable_status,topics_id),查看执行计划发现并没有按照预期选择新的索引,被deleted_at_idx 单列索引干扰,优化器傻傻地认为代价更低!

删掉deleted_at_idx 单列索引,再次查看执行计划

执行效率对比,原sql执行耗时1.5秒,创建新索引后执行耗时0.3秒,效率提升4倍!

二、2号sql原本

select `feeds`.*, (select count(*) from `comments` where `feeds`.`id` = `comments`.`commentable_id` and `comments`.`commentable_type` = 'feeds' and `status` in (0, 1) and (`publish_time` is null or `publish_time` <= '2023-04-08 07:10:18') and (`visible` = 1 or `user_id` = 4809198) and `comments`.`deleted_at` is null) as `comments_count` from `feeds` where (`visible` = 1 or `user_id` = 4809198) and `enable_status` = 1 and `audit_status` in (0, 1) and `risk_status` in (0, 1) and `repostable_id` = 0 and (`feed_title` like '%轩逸e-power%' or `feed_content` like '%轩逸e-power%') and `feeds`.`deleted_at` is null order by `id` desc limit 20 offset 0;

sql执行耗时1秒,执行计划选择repostable_id_idx,表feeds与表comments存在 `feeds`.`id` = `comments`.`commentable_id`,是不是选择 feeds 的主机id作为被驱动表扫描更好呢? 干掉干扰单列索引

查看格式化后的sql

sql执行耗时1秒,执行计划选择repostable_id_idx,表feeds与表comments存在 `feeds`.`id` = `comments`.`commentable_id`,是不是选择 feeds 的主机id作为被驱动表扫描更好呢? 干掉干扰单列索引repostable_id_idx。再次查看执行计划,果然去掉干扰索引后选择主键id扫描数据。

feeds由repostable_id_idx扫描数据量40万条数据&主键回表,变成了根据主键id PRIMARY 只需扫描20条数据,优化后执行耗时0.74秒,感觉还是不够快,大家看到这里有其他想法了吗?

继续回头分析sql, order by `id` desc,mysql索引是b+树且是递增组织的,desc 这是要递减呈现结果集啊!能否用mysql 8.x 的降序索引优化呢?

继续深挖,我们来把sql的desc改为asc 看一波!再次执行sql,执行耗时0.02秒!就是这个条件desc的锅!

三、3号sql原本

select `comments`.*,    (select count(*)     from `comments_reply`     where `comments`.`id` = `comments_reply`.`comment_id`       and `status` in (0,                        1)       and `comments_reply`.`deleted_at` is null) as `replys_count`  from `comments`  where `commentable_id` = 7210702535445709352    and not exists      (select *       from `black_lists`       where `comments`.`user_id` = `black_lists`.`target_id`         and `user_id` = 1134925)    and `status` in (0,                     1)    and (`publish_time` is null         or `publish_time` <= '2023-04-08 07:08:48')    and (`visible` = 1         or `user_id` = 1134925)    and `comments`.`deleted_at` is null  order by `sort` desc,           `score` desc,           `id` desc,           `comments`.`id` desc  limit 15  offset 0;       

格式化sql

 执行耗时1.5秒+,comments表扫描走全表扫描

comments表的表结构

解读执行计划,表comments_reply使用idx_comment_id 索引后与comments 进行关联,但表comments 缺少可利用索引,走全表扫描200万数据,注意from `comments`where `commentable_id` = 7210702535445709352条件,虽然有KEY `comments_commentable_type_commentable_id_index` (`commentable_type`,`commentable_id`) ,但不是索引的最左前缀原则,无法有效利用,明显缺少 commentable_id字段的索引,咱现在创建一个!

原执行耗时1.5秒,优化后,执行耗时0.00秒。comments表由全表扫描200万数据,改变成索引扫描446条数据,666

总结

1、绝大部分情况不要一个字段一个索引

2、索引不是越多越好,无效索引对优化器的最佳执行计划存在干扰与误导

3、mysql 索引是由小到大组织数据的,字段 慎用 desc,可考虑8.x新特性降序索引

4、mysql索引可利用的条件之一为最左前缀原则,创建索引要考虑字段排列顺序

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

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

相关文章

【MySQL数据库原理】MySQL Community安装与配置

目录 安装成功之后查看版本验证1、介绍、安装与配置数据库2、操作MySQL数据库3、MySQL数据库原理安装成功之后查看版本验证 SELECT VERSION();查看mysql版本号 1、介绍、安装与配置数据库 下载安装包:https://download.csdn.net/download/weixin_41194129/87672588 MySQL…

Visual studio C#中通过nuget安装sqlite库及C#中sliqte的用法

以前在Visual studio 的2017版中讲过如何使用sqlite&#xff0c;这里我们再次说说如何使用sqlite&#xff0c;以前Nuget使用还不是很流行很普及&#xff0c;大多数人不知道&#xff0c;但随着VS的升级&#xff0c;Nuget成为安装插件或者引用库文件标准的获取手段&#xff0c;所…

Qt Quick - TabBar

Qt Quick - TabBar使用总结一、概述二、调整选项卡三、Flickable标签三、定制化一、概述 TabBar其实就是选项卡&#xff0c;TabBar是由TabButton控件填充&#xff0c;TabBar可以与任何提供currentIndex属性的布局或容器控件一起使用&#xff0c;如StackLayout或SwipeView。Tab…

Vector - CAPL - CAN x 总线信息获取

在CAN&CANFD测试中&#xff0c;我们经常需要获取到CAN总线的负载、错误帧、过载帧、发送错误等等CAN总线上面的信息&#xff0c;这些信息如此重要&#xff0c;但是如果真的要写代码去实现也是相当不易的&#xff0c;那我们该如何去获取到的呢&#xff1f;下面我们就来一起看…

Object方法

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版&#xff0c;配图更多&#xff0c;CSDN博文图片需要手动上传&#xff0c;因此文章配图较少&#xff0c;看不懂的可以去菜鸡博客参考一下配图&#xff01; 系列文章目录 前端系列文章——传送门 JavaScript系列文章—…

柔性数组【结构体和动态内存的结合】

全文目录前言柔性数组的定义语法柔性数组的特点柔性数组的使用柔性数组的优势前言 很多人可能没有听过柔性数组这个概念&#xff0c;但是在C99中柔性数组是确实存在的。我个人感觉有点像动态内存和结构体的结合。 柔性数组的定义语法 结构中的最后一个元素允许是未知大小的数…

NumPy 秘籍中文第二版:三、掌握常用函数

原文&#xff1a;NumPy Cookbook - Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 在本章中&#xff0c;我们将介绍许多常用函数&#xff1a; sqrt()&#xff0c;log()&#xff0c;arange()&#xff0c;astype()和sum()ceil()&#xff0c;modf()&…

《Java8实战》第1章 Java 8、9、10 以及 11 的变化

如想了解 Oracle 公司对 JDK 的最新支持情况&#xff0c;请访问https://www.oracle.com/technetwork/java/java-se-supportroadmap.html。所有的示例代码均可见于图灵社区本书主页 http://ituring.com.cn/book/2659“随书下载”处。 1.1 为什么要关心 Java 的变化 Java8做的…

[MAUI 项目实战] 手势控制音乐播放器(三): 动画

文章目录吸附动画确定位置平移动画回弹动画使用自定义缓动函数多重动画点击动画项目地址上一章节我们创建了手势容器控件PanContainer&#xff0c;它对拖拽物进行包装并响应了平移手势和点击手势。拖拽物现在虽然可以响应手势操作&#xff0c;但视觉效果较生硬&#xff0c;一个…

总结一下Redis的缓存雪崩、缓存击穿、缓存穿透

缓存是提高系统性能的一种常见手段&#xff0c;其中Redis是一种常用的高性能缓存数据库。但是在使用缓存时&#xff0c;可能会遇到一些问题&#xff0c;比如缓存击穿、缓存穿透、缓存雪崩等问题&#xff0c;本文将介绍这些问题的概念、原因以及解决方案。 缓存击穿 缓存击穿指…

SQL Server 连接查询和子查询

提示&#xff1a; 利用单表简单查询和多表高级查询技能&#xff0c;并且根据查询要求灵活使用内连接查询、外连接查询或子查询等。同时还利用内连接查询的两种格式、三种外连接查询语法格式和子查询的语法格式。 文章目录前言1.查询所有学生的学号、姓名、选修课程号和成绩方法…

Vue学习——【第四弹】

前言 上一篇文章 Vue学习——【第三弹】 中我们了解了MVVM模型&#xff0c;这篇文章接着学习Vue中的数据代理。 简单介绍 数据代理就是**一个对象(A)来代理对另一个对象(B)的属性操作(A一定要包含B)。**直接看定义大家可能觉得有些抽象&#xff0c;我们可以用代码来实现。 …

全景丨0基础学习VR全景制作,后期篇:嵌入视频前期注意事项及后期处理

大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 一、前期拍摄要点 嵌入视频的简介和用途 livepano即完全无缝融合到全景图中的热点嵌入视频。 这种无缝融合是真正无缝&#xff0c;从而让观者产生沉浸感和真实感。例如在场景中放入宠物、让喷泉动起来、灯光…

MPAM中PARTID的虚拟化(Virtualization)

MPAM支持对PARTID的virtualization&#xff0c;需要在满足所有以下条件下才能使用&#xff1a; 在当前的security状态下有实现EL2&#xff1b;支持MPAM virtualization&#xff0c;也就是MPAMIDR_EL1.HAS_HCR等于1&#xff1b; 以下是MPAM中使用virtual-to-physical PARTID ma…

Scala之面向对象

目录 Scala包&#xff1a; 基础语法&#xff1a; Scala包的三大作用&#xff1a; 包名的命名规范&#xff1a; 写包的好处&#xff1a; 包对象&#xff1a; 导包说明&#xff1a; 类和对象&#xff1a; 定义类&#xff1a; 封装&#xff1a; 构造器&#xff1a; 主从…

Spark 之 解析json的复杂和嵌套数据结构

本文主要使用以下几种方法&#xff1a; 1&#xff0c;get_json_object()&#xff1a;从一个json 字符串中根据指定的json 路径抽取一个json 对象 2&#xff0c;from_json()&#xff1a;从一个json 字符串中按照指定的schema格式抽取出来作为DataFrame的列 3&#xff0c;to_j…

【SpringMVC】第一个springmvc项目

需求&#xff1a; 用户在页面发起一个请求&#xff0c; 请求交给springmvc的控制器对象&#xff0c;并显示请求的处理结果&#xff08;在结果页面显示一个欢迎语句&#xff09;。 实现步骤&#xff1a; 新建web maven工程 加入依赖 spring-webmvc依赖&#xff0c;间接把spri…

FLINK 在蚂蚁大规模金融场景的平台建设

摘要&#xff1a;本文整理自蚂蚁集团高级技术专家、蚂蚁集团流计算平台负责人李志刚&#xff0c;在 Flink Forward Asia 2022 平台建设专场的分享。本篇内容主要分为四个部分&#xff1a; 主要挑战架构方案核心技术介绍未来规划点击查看直播回放和演讲 PPT 一、主要挑战 1.1 金…

【 Spring MVC 核心功能(三) - 输出数据】

文章目录引言一、返回静态页面二、返回非静态页面的数据三、返回 JSON 对象四、请求转发(forward)和请求重定向(redirect)五、拓展&#xff1a;IDEA 热部署(热加载)3.1 添加 SpringBoot DevTools 框架3.2 开起 IDEA 的自动编译3.3 开起运行中的热部署3.4 使用 debug 启动项目引…

【机器学习】SoftMax多分类---学习笔记

SoftMax---学习笔记softMax分类函数定义&#xff1a;softmax分类损失函数softMax分类函数 首先给一个图&#xff0c;这个图比较清晰地告诉大家softmax是怎么计算的。 (图片来自网络) 定义&#xff1a; 给定以歌nknknk矩阵W(w1,w2,...,wk)W(w_1,w_2,...,w_k)W(w1​,w2​,...,w…