MySQL索引原理之查询优化

MySQL索引原理之查询优化

1、慢查询定位

  • 开启慢查询日志

    查看 MySQL 数据库是否开启了慢查询日志和慢查询日志文件的存储位置的命令如下:

    SHOW VARIABLES LIKE '%slow_query_log%'
    

    通过如下命令开启慢查询日志:

    SET global slow_query_log = 1;
    SET global slow_query_log_file = 'QIXI-slow.log';
    SET global log_queries_not_using_indexes = 1;
    SET long_query_time = 10;
    

    long_query_time:指定慢查询的阀值,单位秒。如果SQL执行时间超过阀值,就属于慢查询记录到日志文件中。

    log_queries_not_using_indexes:表示会记录没有使用索引的查询SQL。前提是slow_query_log 的值为ON,否则不会奏效。

  • 查看慢查询日志

    • 文本方式查看

      直接使用文本编辑器打开slow.log日志即可。

      MySql_81

      • time:日志记录的时间
      • User@Host:执行的用户及主机
      • Query_time:执行的时间
      • Lock_time:锁表时间
      • Rows_sent:发送给请求方的记录数,结果数量
      • Rows_examined:语句扫描的记录条数
      • SET timestamp:语句执行的时间点
      • select…:执行的具体的SQL语句
    • 使用mysqldumpslow查看

      MySQL 提供了一个慢查询日志分析工具mysqldumpslow,可以通过该工具分析慢查询日志内容。

      在 MySQL bin目录下执行下面命令可以查看该使用格式。(需安装perl)

      perl mysqldumpslow.pl --help
      

      运行如下命令查看慢查询日志信息:

      perl mysqldumpslow.pl -t 5 -s at C:\ProgramData\MySQL\Data\QIXI-slow.log
      

      除了使用mysqldumpslow工具,也可以使用第三方分析工具,比如pt-query-digest、mysqlsla等。

2、慢查询优化

  • 索引和慢查询

    • 如何判断是否为慢查询?

      MySQL判断一条语句是否为慢查询语句,主要依据SQL语句的执行时间,它把当前语句的执行时间跟 long_query_time 参数做比较,如果语句的执行时间 > long_query_time,就会把这条执行语句记录到慢查询日志里面。long_query_time 参数的默认值是 10s,该参数值可以根据自己的业务需要进行调整。

    • 如何判断是否应用了索引?

      SQL语句是否使用了索引,可根据SQL语句执行过程中有没有用到表的索引,可通过 explain 命令分析查看,检查结果中的 key 值,是否为NULL。

    • 应用了索引是否一定快?

      下面我们来看看下面语句的 explain 的结果,你觉得这条语句有用上索引吗?比如

      select * from user where id>0;
      

      虽然使用了索引,但是还是从主键索引的最左边的叶节点开始向右扫描整个索引树,进行了全表扫描,此时索引就失去了意义。

      而像 select * from user where id = 2; 这样的语句,才是我们平时说的使用了索引。它表示的意思是,我们使用了索引的快速搜索功能,并且有效地减少了扫描行数。

    查询是否使用索引,只是表示一个SQL语句的执行过程;而是否为慢查询,是由它执行的时间决定的,也就是说是否使用了索引和是否是慢查询两者之间没有必然的联系。

    我们在使用索引时,不要只关注是否起作用,应该关心索引是否减少了查询扫描的数据行数,如果扫描行数减少了,效率才会得到提升。对于一个大表,不止要创建索引,还要考虑索引过滤性,过滤性好,执行速度才会快。

  • 提高索引过滤性

    假如有一个5000万记录的用户表,通过sex='男’索引过滤后,还需要定位3000万,SQL执行速度也不会很快。其实这个问题涉及到索引的过滤性,比如1万条记录利用索引过滤后定位10条、100 条、1000条,那他们过滤性是不同的。索引过滤性与索引字段、表的数据量、表设计结构都有关系。

    • 下面我们看一个案例:

      表:student

      字段:id,name,sex,age

      create table student(-> id int primary key auto_increment,-> name varchar(20),-> sex char(1),-> age int)engine=innodb charset=utf8;
      

      造数据:随便插入几条数据后执行如下SQL

      insert into student (name,sex,age) select name,sex,age from student; 
      

      SQL案例:

      select * from student where age=18 and name like 'zhang%';(全表扫描)
      
    • 优化1

      create index age_1 on student(age);
      

      MySql_82

    • 优化2

      create index age_name on student(age,name);
      

      MySql_83

    • 优化3

      再进一步优化,我们可以把名字的第一个字和年龄做一个联合索引,这里可以使用 MySQL 5.7 引入的虚拟列来实现。

      -- 为student表添加first_name虚拟列,以及联合索引(first_name,age)
      alter table student add first_name varchar(5) generated always as(left(name,5)),add index(first_name,age);
      

      MySql_84

  • 慢查询原因总结

    • 全表扫描:explain分析type属性all
    • 全索引扫描:explain分析type属性index
    • 索引过滤性不好:靠索引字段选型、数据量和状态、表设计
    • 频繁的回表查询开销:尽量少用select *,使用覆盖索引

3、分页查询优化

  • 一般性分页

    般的分页查询使用简单的 limit 子句就可以实现。limit格式如下:

    SELECT * FROM 表名 LIMIT [offset,] rows
    
    • 第一个参数指定第一个返回记录行的偏移量,注意从0开始;
    • 第二个参数指定返回记录行的最大数目;
    • 如果只给定一个参数,它表示返回最大的记录行数目;

    思考1:如果偏移量固定,返回记录量对执行时间有什么影响?

    select * from student limit 10000,1;
    select * from student limit 10000,10;
    select * from student limit 10000,100;
    select * from student limit 10000,1000;
    select * from student limit 10000,10000;
    

    结果:在查询记录时,返回记录量低于100条,查询时间基本没有变化,差距不大。随着查询记录量越大,所花费的时间也会越来越多。

    思考2:如果查询偏移量变化,返回记录数固定对执行时间有什么影响?

    select * from student limit 1,100;
    select * from student limit 10,100;
    select * from student limit 100,100;
    select * from student limit 1000,100;
    select * from student limit 10000,100;
    

    结果:在查询记录时,如果查询记录量相同,偏移量超过100后就开始随着偏移量增大,查询时间急剧的增加。(这种分页查询机制,每次都会从数据库第一条记录开始扫描,越往后查询越慢,而且查询的数据越多,也会拖慢总查询速度。)

    MySql_84

  • 分页优化方案

    第一步:利用覆盖索引优化

    select * from student limit 10000,100;
    select id from student limit 10000,100;
    

    第二步:利用子查询优化

    select * from student limit 10000,100;
    select * from student where id>= (select id from user limit 10000,1) limit 100;
    

    原因:使用了id做主键比较(id>=),并且子查询使用了覆盖索引进行优化。

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

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

相关文章

ArchGuard 架构分析器发布:多语言、跨项目架构数据生成,助力 AI 时代知识挖掘...

TL;DR:https://github.com/archguard/archguard 过去的几个月里,我们一直在探索用 AI 辅助跨项目、跨大量微服务的系统的开发。其中一个重要的话题就是,从现有的软件架构去生成知识,文档是落后、多版本的, 只有代码才保…

NLP论文速读(多伦多大学)|利用人类偏好校准来调整机器翻译的元指标

论文速读|MetaMetrics-MT: Tuning Meta-Metrics for Machine Translation via Human Preference Calibration 论文信息: 简介: 本文的背景是机器翻译(MT)任务的评估。在机器翻译领域,由于不同场景和语言对的需求差异&a…

工程车识别算法平台LiteAIServer算法定制工程车类型检测算法:建筑工地安全管理的得力助手

随着科技的飞速发展,智能化技术正在逐步改变我们的生活方式,特别是在交通管理和安全管理领域。其中,算法定制LiteAIServer工程车类型检测算法以其高效、准确和实时的特性,成为了建筑工地管理、矿山开采以及物流运输等多个领域的重…

机器学习2

三、特征工程 接机器学习1 4、特征降维 4.2、主成分分析PCA 从原始特征空间中找到一个新的坐标系统,使得数据在新坐标轴上的投影能够最大程度地保留数据的方差,同时减少数据的维度。 保留信息/丢失信息信息保留的比例 from sklearn.decomposition imp…

【Linux之权限】提升篇

前言 在前两篇文章里,我们已经学习了Linux中权限的理论、实践和重点,接下来我们将进一步提升对Linux权限的全面认知。虽是拓展,其实还是重点。 本文内容并不多,那我们就开始吧。 目录的权限该如何理解呢? 如果我想进…

亮数据结合AI大模型,实现数据自由

目录 一、获取网络数据的挑战1、反爬虫机制的威胁2、IP封锁与访问频率控制3、数据隐私与法律合规 二、亮数据动态代理:数据采集的最佳拍档1、高质量IP资源2、智能调度与自动切换3、合规与隐私保护4、多场景应用支持 三、使用亮数据代理 IP进行网络数据抓取1、引入 r…

elasticsearch是如何实现master选举的?

大家好,我是锋哥。今天分享关于【elasticsearch是如何实现master选举的?】面试题。希望对大家有帮助; elasticsearch是如何实现master选举的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Elasticsearch 中&…

EtherNet/IP转Profinet网关连接发那科机器人配置实例解析

本案例主要展示了如何通过Ethernet/IP转Profinet网关实现西门子1200PLC与发那科搬运机器人的连接。所需的设备有西门子1200PLC、开疆智能Ethernet/IP转Profinet网关以及Fanuc机器人。 具体配置步骤:打开西门子博图配置软件,添加PLC。这是配置的第一步&am…

Uniapp运行环境判断和解决跨端兼容性详解

Uniapp运行环境判断和解决跨端兼容性 开发环境和生产环境 uniapp可通过process.env.NODE_ENV判断当前环境是开发环境还是生产环境,一般用于链接测试服务器或者生产服务器的动态切换。在HX中,点击运行编译出来的代码是开发环境,点击发行编译…

C语言 for 循环:解谜数学,玩转生活!

放在最前面的 🎈 🎈 我的CSDN主页:OTWOL的主页,欢迎!!!👋🏼👋🏼 🎉🎉我的C语言初阶合集:C语言初阶合集,希望能…

【专题】2024AIGC创新应用洞察报告汇总PDF洞察(附原数据表)

原文链接:https://tecdat.cn/?p38310 在科技日新月异的今天,人工智能领域正以前所未有的速度发展,AIGC(人工智能生成内容)成为其中最耀眼的明珠。从其应用场景的不断拓展,到对各行业的深刻变革&#xff0…

.NET桌面应用架构Demo与实战|WPF+MVVM+EFCore+IOC+DI+Code First+AutoMapper

目录 .NET桌面应用架构Demo与实战|WPFMVVMEFCoreIOCDICode FirstAutoPapper技术栈简述项目地址:功能展示项目结构项目引用1. 新建模型2. Data层,依赖EF Core,实现数据库增删改查3. Bussiness层,实现具体的业务逻辑4. Service层&am…

两种柑橘物种中WRKY转录因子的鉴定和比较-文献精读82

Genome-wide identification and comparative expression profiling of the WRKY transcription factor family in two Citrus species with different Candidatus Liberibacter asiaticus susceptibility 全基因组范围内鉴定和比较两种对柑橘黄龙病菌(Candidatus …

Kafka中ACKS LSO LEO LW HW AR ISR OSR解析

名称解释 ACKS(Acknowledgments)确认、回执 LW(Low watermark)低水位、LSO(Log start offset)起始偏移量 HW(High watermark)高水位 LEO(Log end offset)…

vue实现展示并下载后端返回的图片流

// 点击下载 downLoadCode() {const image new Image();image.setAttribute("crossOrigin", "anonymous");image.onload () > {const canvas document.createElement("canvas");canvas.width image.width;canvas.height image.height;c…

c++:模板

1.泛型编程 在认识模板之前,我们首先要认识泛型编程 泛型编程是一种编程范式,它使得算法和数据结构能够独立于特定数据类型进行设计和实现。通过使用泛型,开发者可以编写一次代码,然后在不同的数据类型上进行重用,从…

Linux下安装配置redis详细教程,并配置哨兵模式,redis配置文件中文详解

redis版本为redis-3.2.12,使用工具将安装包上传到data目录。 redis.jpeg 在data目录下创建文件夹redis,将redis安装在此目录。 第一步:解压。 cd data tar -zxvf redis-3.2.12.tar.gz第二步:安装,PREFIX/data/redis用…

R语言数据分析案例45-全国汽车销售数据分析(可视化与回归分析)

一、研究背景 随着经济的发展和人们生活水平的提高,汽车已经成为人们日常生活中不可或缺的交通工具之一。汽车市场的规模不断扩大,同时竞争也日益激烈。对于汽车制造商和经销商来说,深入了解汽车销售数据背后的规律和影响因素,对…

Java 网络编程:Socket 与网络通信

1 引言 在古代,由于通信不便利,人们利用鸽子的飞行能力和方向辨识能力,驯化鸽子进行消息传递,即所谓的“飞鸽传书”。在现代计算机网络中,套接字(Socket)扮演了类似的角色。套接字是应用程序通…

编程之路,从0开始:结构体详解

目录 前言 正文 1、结构体引入 2、结构体的声明 3、typedef 4、结构体的匿名声明 5、结构的自引用 (1)链表 (2)自引用 6、结构体内存对齐 (1)对齐规则 (2)题目 &#x…