MySQL之查询性能优化(十)

查询性能优化

MySQL查询优化器的局限性

松散索引扫描

由于历史原因,MySQL并不支持松散索引扫描,也就无法按照不连续的方式扫描一个索引。通常,MySQL的索引扫描需要先定义一个起点和终点,即使需要的数据只是这段索引中很少数的几个,MySQL仍需要扫描这段儿索引中的每一个条目。下面我们通过一个示例说明这点。假设我们有如下索引(a,b),有下面的查询:

mysql>SELECT ... FROM tbl WHERE b BETWEEN 2 AND 3;

因为索引的前导字段是列a,但是在查询中只指定了字段b,MySQL无法使用这个索引,从而只能通过全表扫描找到匹配的行,在这里插入图片描述
如图所示。了解索引的物理结构的话,不难发现还可以有一个更快的办法执行上面的查询。索引的物理结构(不是存储引擎的API)使得可以先扫描a列的第一个值对应的b列的范围,然后再跳到a列不同第二个不同值扫描对应的b列的范围。在这里插入图片描述
如图所示展示了如果由MySQL来实现这个过程会怎样。注意到,这时就无须再使用WHERE子句过滤,因为松散索引扫描已经跳过了所有不需要的记录。上面是一个简单的例子,除了松散索引扫描,新增一个合适的索引当然也可以优化上述查询。但对于某些场景,增加索引是没用的,例如,对于第一个索引列是范围条件,第二个索引列是等值条件的查询,靠增加索引就无法解决问题。
MySQL5.0之后的版本,在某些特殊的场景下是可以使用松散索引扫描的,例如,在一个分组查询中需要找到分组的最大值和最小值:

mysql> EXPLAIN SELECT actor_id, MAX(film_id)
    -> FROM sakila.film_actor
    -> GROUP BY actor_id\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: film_actor
   partitions: NULL
         type: range
possible_keys: PRIMARY,idx_fk_film_id
          key: PRIMARY
      key_len: 2
          ref: NULL
         rows: 201
     filtered: 100.00
        Extra: Using index for group-by

在EXPLAIN中的Extra字段显示"Using index for group-by",表示这里将使用松散索引扫描,不过如果MySQL能写上"loose index probe",相信会更好理解。在MySQL很好地支持松散索引扫描之前,一个简单的绕过问题的办法就是给前面的列加上可能的常数值。在MySQL5.6之后的版本,关于松散索引扫描的一些限制将会通过"索引下推(index condition pushdown)"的方式解决

最大值和最小值优化

对于MIN()和MAX()查询,MySQL的优化做得并不好。这里有一个例子:

mysql> SELECT MIN(actor_id) FROM sakila.actor WHERE first_name='PENELOPE';

因为在first_name字段上并没有索引,因此MySQL将会进行一次全表扫描。如果MySQL能够进行主键扫描,那么理论上,当MySQL读到的第一个满足条件的记录的时候,就是我们需要找到的最小值了,因为主键是严格按照actor_id字段的大小顺序排列的。但是MySQL这时只会做全表扫描,我们可以通过查看SHOW STATUS的全表扫描计数器来验证这一点。一个曲线的优化办法是移除MIN(),然后使用LIMIT来讲查询重写如下:

mysql> SELECT actor_id FROM sakila.actor USE INDEX(PRIMARY)
    -> WHERE first_name = 'PENELOPE' LIMIT 1;
+----------+
| actor_id |
+----------+
|        1 |
+----------+
1 row in set (0.00 sec)

这个策略可以让MySQL扫描尽可能少的记录数。如果你是一个完美主义者,可能会说这个SQL已经无法表达她的本意了。一般我们通过SQL告诉服务器我们需要什么数据,由服务器来决定如何最优地获取数据,不过在这个案例中,我们其实是告诉MySQL如何去获取我们需要的数据,通过SQL并不能一眼就看出我们其实是想要一个最小值。确实如此,有时候为了获得更高的性能,我们不得不放弃一些原则

在同一个表上查询和更新

MySQL不允许对同一个张表同时进行查询和更新。这其实并不是优化器的限制,如果清楚MySQL是如何执行查询,就可以避免这种情况。下面是一个无法运行的SQL,虽然这是一个符合标准的SQL语句。这个SQL语句尝试将两个表中相似行的数量记录到字段cnt中:

mysql> UPDATE tbl AS outer_tbl
    -> SET cnt = (
    -> SELECT COUNT(*) FROM tbl AS inner_tbl
    -> WHERE inner_tbl.type = outer_tbl.type
    -> );
ERROR 1093(HY000):You can't specify target table 'outer_tbl' for update in FROM clause

可以通过使用生成表的形式来绕过上面的限制,因为MySQL只会把这个表当作一个临时表来处理。实际上,这执行了两个查询:一个是子查询中的SELECT语句,另一个是多表关联UPDATE,只是关联的表是一个临时表。子查询会在UPDATE语句打开表之前就完成。所以下面的查询将会正常执行:

mysql> UPDATE tbl
    -> INNER JOIN (
    -> SELECT type, count(*) AS cnt
    -> FROM tbl
    -> GROUP BY type
    -> ) AS der USING(type)
    -> SET tbl.cnt = der.cnt;

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

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

相关文章

WSDM2022推荐系统相关论文整理(一)

2022年第15届国际网络搜索与数据挖掘会议WSDM在2022年2月21日到25日于线上举行,共收到了786份有效投稿,最终录取篇数为159篇,录取率为20.23%。作为主流的搜索与数据挖掘会议,论文的话题主要侧重于搜索、推荐以及数据挖掘领域&…

【机器学习基础】Python编程06:五个实用练习题的解析与总结

Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面: 简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。 丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些…

【BOM02】本地存储

一:什么是本地存储 数据存储在用户浏览器中,用户设置、读取方便,同时页面刷新时不会丢失数据。存储在浏览器中数据约5M,分为sessionStorage和localStorage两种存储方式 二:localStorage存储 作用 将数据永久存储在…

SSM整合总结

一.核心问题 (一)两个容器 web容器 web相关组件(controller,springmvc核心组件) root容器 业务和持久层相关组件(service,aop,tx,dataSource,mybatis,mapper等) 父容器:root容器,盛放service、mapper、…

【人工智能】流行且重要的智能算法整理

✍🏻记录学习过程中的输出,坚持每天学习一点点~ ❤️希望能给大家提供帮助~欢迎点赞👍🏻收藏⭐评论✍🏻指点🙏 小记: 今天在看之前写的文档时,发现有人工智能十大算法的内容&#xf…

Java概述 , Java环境安装 , 第一个Hello World

环境变量,HelloWorld 1.会常用的dos命令 2.会安装java所需要的环境(jdk) 3.会配置java的环境变量 4.知道java开发三步骤 5.会java的入门程序(HelloWorld) 6.会三种注释方式 7.知道Java入门程序所需要注意的地方 8.知道println和print的区别第一章 Java概述 1.1 JavaSE体系介绍…

Django 里的表格内容做修改

当Django里表格内容需要做修改&#xff0c;可以这么操作。 先看效果图 修改后的表格 1. 先得在 asset_list.html 里修改。你们的html有可能跟我不一样 <table border"1px"><thead><tr><th>ID</th><th>标题</th><th…

软件测试--Linux快速入门

文章目录 软件测试-需要掌握的Linux指令Linux命令操作技巧Linx命令的基本组成常用命令 软件测试-需要掌握的Linux指令 Linux命令操作技巧 使用Tab键自动补全上下键进行翻找之前输入的命令命令执行后无法停止使用CtrC,结束屏幕输出 Linx命令的基本组成 命令 [-选项] [参数] …

1.Linux入门

文章目录 一、介绍1.1 操作系统1.2 Linux1.3 虚拟机1.4 安装 CentOS7 二、远程连接 Linux2.1 FinalShell2.2 远程连接Linux 三、扩展3.1 WSL3.2 虚拟机快照 一、介绍 1.1 操作系统 我们平常所用的电脑是个人桌面操作系统&#xff0c;也就是Windows或者是macOS 目前我们要学的…

(2024,ViT,小波变换,图像标记器,稀疏张量)基于小波的 ViT 图像标记器

Wavelet-Based Image Tokenizer for Vision Transformers 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0 摘要 1 引言 3 基于小波的图像压缩简介 4 图像标记器 4.1 像素空间标记嵌…

短视频直播教学课程小程序的作用是什么

只要短视频/直播做的好&#xff0c;营收通常都不在话下&#xff0c;近些年&#xff0c;线上自媒体行业热度非常高&#xff0c;每条细分赛道都有着博主/账号&#xff0c;其各种优势条件下也吸引着其他普通人冲入。 然无论老玩家还是新玩家&#xff0c;面对平台不断变化的规则和…

Docker搭建ELKF日志分析系统

Docker搭建ELKF日志分析系统 文章目录 Docker搭建ELKF日志分析系统资源列表基础环境一、系统环境准备1.1、创建所需的映射目录1.2、修改系统参数1.3、单击创建elk-kgc网络桥接 二、基于Dockerfile构建Elasticsearch镜像2.1、创建Elasticsearch工作目录2.2、上传资源到指定工作路…

鸿蒙开发的南向开发和北向开发

鸿蒙开发主要分为设备开发和应用开发两个方向&#xff0c;也叫南向开发和北向开发&#xff1a; 鸿蒙设备开发(南向开发&#xff09;&#xff0c;要侧重于硬件层面的开发&#xff0c;涉及硬件接口控制、设备驱动开发、鸿蒙系统内核开发等&#xff0c;目的是使硬件设备能够兼容并…

端午假期来临,来使用闪侠惠递便宜寄快递吧!

相信很多人和我一样&#xff0c;每当需要寄快递时&#xff0c;总是感到十分头疼。不同的快递公司有不同的价格、时效和服务质量等等&#xff0c;选择起来真的很不容易。但是现在有了闪侠惠递来帮大家寄快递吧&#xff0c;这个问题就可以迎刃而解了&#xff01;小编奉劝大家快来…

性能级NVMe全闪存储系统开箱评测

近日&#xff0c;我们对一款备受瞩目的Infortrend普安科技推出更高性能的存储产品——性能级NVMe全闪存储系统GS 5024UE 进行评测&#xff0c;这款设备搭载第五代IntelXeon处理器&#xff0c;性能达到50GB/s、1.3M IOPS与0.3毫秒延迟。下面对此款设备从外观、配置、产品性能及适…

如何使用Vuforia AR进行增强现实技术的开发?

前言 今天是坚持写博客的第17天&#xff0c;很高兴自己可以一直坚持下来。我们今天来讲讲怎么使用Vuforia AR进行增强现实的开发。 我们需要在今天的开发中用到Vuforia AR和2018版的Unity3d 什么是Vuforia AR Vuforia AR是基于实时计算摄影机影像的位置及角度&#xff0c;并…

树的遍历详解

目录 树的静态写法 树的先根遍历 树的层次遍历 从树的遍历看DFS和BFS DFS与先根遍历 BFS与层次遍历 树的静态写法 这里讨论的树是一般意义上的树&#xff0c;即子结点个数不限且子节点没有先后次序的树。 建议使用静态写法进行结点的定义 struct node{typename data;i…

“新高考”下分班怎么分?

来自安徽的张女士告诉我&#xff1a;上一年孩子升入了高中&#xff0c;但没想到才高一&#xff0c;孩子就面临了一个困难的挑选&#xff1a;312”分班&#xff01; 什么是312”分班呢&#xff1f;许多人或许不明白&#xff0c;便是要求学生在高一入学时&#xff0c;针对于3门必…

Mac - Node/Java 配置安装全流程

Mac - Node/Java 配置安装全流程 一. Git 安装二. Java 相关安装2.1 jenv 版本控制工具2.2 JDK1.8 和 JDK21的安装2.3 maven 安装 三. Node 相关安装3.1 nvm 版本控制工具3.2 Node 版本安装 一. Git 安装 1.我们首先安装一下Homebrew&#xff0c;这个工具很有用&#xff0c;能…

Spring Security系列之PasswordEncoder

概述 任何一个登录系统的密码不能明文存储&#xff0c;万一发生数据库泄漏事故&#xff08;不管是内部人员导出数据库数据还是被黑客攻击破解数据库实例节点拿到数据库数据等&#xff0c;又或者是其他情况造成的&#xff09;&#xff0c;将产生巨大的损失。因此明文密码在存储…