0

0

MySQL查询优化器浅析(二)_MySQL

php中文网

php中文网

发布时间:2016-06-01 14:00:47

|

1108人浏览过

|

来源于php中文网

原创

8 范围存取类型

  一些表达式可以使用索引,但是属于索引的范围查找。这些表达式通常对应的操作符是:>、>=、

  对优化器而言,如下表达式:

  column1 IN (1,2,3)

  该表达式与下面的表达式是等价的:

  column1 = 1 OR column1 = 2 OR column1 = 3

  并且MySQL也是认为它们是等价的,所以没必要手动将IN改成OR,或者把OR改成IN。

  优化器将会对下面的表达式使用索引范围查找:

  column1 LIKE 'x%'

  但对下面的表达式就不会使用到索引了:

  column1 LIKE '%x'

  这是因为当首字符是通配符的时候,没办法使用到索引进行范围查找。

  对优化器而言,如下表达式:

  column1 BETWEEN 5 AND 7

  该表达式与下面的表达式是等价的:

  column1 >= 5 AND column1

  同样,MySQL也认为它们是等价的。

  如果需要检查过多的索引键值,优化器将放弃使用索引范围查找,而是使用全表扫描的方式。这样的情况经常出现如下的情况下:索引是多层次的二级索引,查询条件是''的情况。

9 索引存取类型

  考虑如下的查询语句:

  SELECT column1 FROM Table1;

  如果column1是索引列,优化器更有可能选择索引全扫描,而不是采用表全扫描。这是因为该索引覆盖了我们所需要查询的列。

  再考虑如下的查询语句:

  SELECT column1,column2 FROM Table1;

  如果索引的定义如下,那么就可以使用索引全扫描:

  CREATE INDEX … ON Table1(column1,column2);

  也就是说,所有需要查询的列必须在索引中出现。

10 转换

  MySQL对简单的表达式支持转换。比如下面的语法:

  WHERE -5 = column1

  转换为:

  WHERE column1 = -5

  尽管如此,对于有数学运算存在的情况不会进行转换。比如下面的语法:

  WHERE 5 = -column1

  不会转换为:

  WHERE column1 = -5

11 AND

  带AND的查询的格式为: AND ,考虑如下的查询语句:

  WHERE column1='x' AND column2='y'

  优化的步骤:

  1) 如果两个列都没有索引,那么使用全表扫描。

  2) 否则,如果其中一个列拥有更好的存取类型(比如,一个具有索引,另外一个没有索引;再或者,一个是唯一索引,另外一个是非唯一索引),那么使用该列作为驱动表达式。

  3) 否则,如果两个列都分别拥有索引,并且两个条件对应的存取类型是一致的,那么选择定义索引时的先定义的索引。

  举例如下:

  CREATE TABLE Table1 (s1 INT,s2 INT);

  CREATE INDEX Index1 ON Table1(s2);

  CREATE INDEX Index2 ON Table1(s1);

  …

  SELECT * FROM Table1 WHERE s1=5 AND s2=5;

  优化器选择s2=5作为驱动表达式,因为s2上的索引是新建的。

12 OR

Canva
Canva

使用Canva可画,轻松创建专业设计

下载

  带OR的查询格式为: OR ,考虑如下的查询语句:

  WHERE column1='x' OR column2='y'

  优化器做出的选择是采用全表扫描。

  当然,在一些特定的情况,可以使用索引合并,这里不做阐述。

  如果两个条件里面设计的列是同一列,那么又是另外一种情况,考虑如下的查询语句:

  WHERE column1='x' OR column1='y'

  在这种情况下,该查询语句采用索引范围查找。

13 UNION

  所有带UNION的查询语句都是单独优化的,考虑如下的查询语句:


以下是引用片段:
  SELECT * FROM Table1 WHERE column1='x'
  UNION ALL
  SELECT * FROM Table1 WHERE column2='y'


  如果column1与column2都是拥有索引的,每个查询都是使用索引查询,然后合并结果集。

14 NOT,

  考虑如下的表达式:

  Column1 5

  从逻辑上讲,该表达式等价于下面的表达式:

  Column15

  然而,MySQL不会进行这样的转换。如果你觉得使用范围查找会更好一些,应该手动地进行转换。

  考虑如下的表达式:

  WHERE NOT (column1!=5)

  从逻辑上讲,该表达式等价于下面的表达式:

  WHERE column1=5

  同样地,MySQL也不会进行这样的转换。

15 ORDER BY

  一般而言,ORDER BY的作用是使结果集按照一定的顺序排序,如果可以不经过此操作就能产生顺序的结果,可以跳过该ORDER BY操作。

  考虑如下的查询语句:

  SELECT column1 FROM Table1 ORDER BY 'x';

  优化器将去除该ORDER BY子句,因为此处的ORDER BY子句没有意义。

  再考虑另外的一个查询语句:

  SELECT column1 FROM Table1 ORDER BY column1;

  在这种情况下,如果column1类上存在索引,优化器将使用该索引进行全扫描,这样产生的结果集是有序的,从而不需要进行ORDER BY操作。

  再考虑另外的一个查询语句:

  SELECT column1 FROM Table1 ORDER BY column1+1;

  假设column1上存在索引,我们也许会觉得优化器会对column1索引进行全扫描,并且不进行ORDER BY操作。实际上,情况并不是这样,优化器是使用column1列上的索引进行全扫表,仅仅是因为索引全扫描的效率高于表全扫描。对于索引全扫描的结果集仍然进行ORDER BY排序操作。

16 GROUP BY

  这里列出对GROUP BY子句以及相关集函数进行优化的方法:

  1) 如果存在索引,GROUP BY将使用索引。

  2) 如果没有索引,优化器将需要进行排序,一般情况下会使用HASH表的方法。

  3) 如果情况类似于“GROUP BY x ORDER BY x”,优化器将会发现ORDER BY子句是没有必要的,因为GROUP BY产生的结果集是按照x进行排序的。

  4) 尽量将HAVING子句中的条件提升中WHERE子句中。

  5) 对于MyISAM表,“SELECT COUNT(*) FROM Table1;”直接返回结果,而不需要进行表全扫描。但是对于InnoDB表,则不适合该规则。补充一点,如果column1的定义是NOT NULL的,那么语句“SELECT COUNT(column1) FROM Table1;”等价于“SELECT COUNT(*) FROM Table1;”。

  6) 考虑MAX()以及MIN()的优化情况。考虑下面的查询语句:


以下是引用片段:
  SELECT MAX(column1)
  FROM Table1
  WHERE column1


  如果column1列上存在索引,优化器使用'a'进行索引定位,然后返回前一条记录。

  7) 考虑如下的查询语句:

  SELECT DISTINCT column1 FROM Table1;

  在特定的情况下,语句可以转化为:

  SELECT column1 FROM Table1 GROUP BY column1;

  该转换的前提条件是:column1上存在索引,FROM上只有一个单表,没有WHERE条件并且没有LIMIT条件

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

463

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

135

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

64

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

26

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

14

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

524

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

53

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

微信小程序开发之API篇
微信小程序开发之API篇

共15课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号