普通程序员必须掌握的SQL优化技巧

不管是工作中,还是面试中,基本上都需要搞定一些SQL优化技巧,比如说使用explain查看SQL的执行计划,然后,针对执行计划对SQL进行优化。

关于explain的使用以及相关字段的分析,现在基本已经是程序员标配了。

不会的,请认真看完吧。

1、什么是MySQL执行计划

要对执行计划有个比较好的理解,需要先对MySQL的基础结构及查询基本原理有简单的了解。

MySQL本身的功能架构分为三个部分,分别是 应用层、逻辑层、物理层,不只是MySQL ,其他大多数数据库产品都是按这种架构来进行划分的。

应用层,主要负责与客户端进行交互,建立链接,记住链接状态,返回数据,响应请求,这一层是和客户端打交道的。
逻辑层,主要负责查询处理、事务管理等其他数据库功能处理,以查询为例。

首先接收到查询SQL之后,数据库会立即分配一个线程对其进行处理,第一步查询处理器会对SQL查询进行优化,优化后会生成执行计划,然后交由计划执行器来执行。

计划执行器需要访问更底层的事务管理器,存储管理器来操作数据,他们各自的分工各有不同,最终通过调用物理层的文件获取到查询结构信息,将最终结果响应给应用层。

物理层,实际物理磁盘上存储的文件,主要有分文数据文件,日志文件。

通过上面的描述,生成执行计划是执行一条SQL必不可少的步骤,一条SQL性能的好坏,可以通过查看执行计划很直观的看出来,执行计划提供了各种查询类型与级别,方面我们进行查看以及为作为性能分析的依据。

2、如何分析执行计划

MySQL为我们提供了 explain 关键字来直观的查看一条SQL的执行计划。

explain显示了MySQL如何使用索引来处理select语句以及连接表,可以帮助选择更好的索引和写出更优化的查询语句。

下面我们使用 explain 做一个查询,如下:

mysql> explain select * from payment;+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra |+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+|  1 | SIMPLE      | payment | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 16086 |   100.00 | NULL  |+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+1 row in set, 1 warning (0.01 sec)

查询结构中有12列,理解每一列的含义,对理解执行计划至关重要,下面用一个表格的形式进行说明。

列名 说明

idSELECT识别符,这是SELECT的查询序列号。select_typeSELECT类型,可以为以下任何一种:SIMPLE:简单SELECT(不使用UNION或子查询)PRIMARY:最外面的SELECTUNION:UNION中的第二个或后面的SELECT语句DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询UNION RESULT:UNION 的结果SUBQUERY:子查询中的第一个SELECTDEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询DERIVED:导出表的SELECT(FROM子句的子查询)table输出的行所引用的表partitions如果查询是基于分区表的话,显示查询将访问的分区。type联接类型。下面给出各种联接类型,按照从最佳类型到最坏类型进行排序:
system:表仅有一行(=系统表)。这是const联接类型的一个特例。
const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。
ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。
ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。
index_merge:该联接类型表示使用了索引合并优化方法。
unique_subquery:该类型替换了下面形式的IN子查询的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
index_subquery:该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
range:只检索给定范围的行,使用一个索引来选择行(建议,最差也要这个级别)。
index:该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
ALL:对于每个来自于先前的表的行组合,进行完整的表扫描,说明查询就需要优化了。一般来说,得保证查询至少达到range级别,最好能达到ref。
以上system最好,依次递减,ALL最差possible_keys指出MySQL能使用哪个索引在该表中找到行key显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。key_len显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。在不损失精确性的情况下,长度越短越好ref显示使用哪个列或常数与key一起从表中选择行。rows显示MySQL认为它执行查询时必须检查的行数。多行之间的数据相乘可以估算要处理的行数。filtered显示了通过条件过滤出的行数的百分比估计值。Extra该列包含MySQL解决查询的详细信息
Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
Select tables optimized away MySQL根本没有遍历表或索引就返回数据了,表示已经优化到不能再优化了
Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。
Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行,说明查询就需要优化了。
Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。
Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果,说明查询就需要优化了。
Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。
Using sort_union(…), Using union(…), Using intersect(…):这些函数说明如何为index_merge联接类型合并索引扫描。
Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。

根据上述表格,可以在执行计划分析上提供很好的帮助。

注意:如果是为了应付面试,最好是能背下来,不能全背下来的情况,也要能说上个123,然后就说,记不得这么多,可以翻阅相关文档来对照着优化SQL。

以上就是普通程序员必须掌握的SQL优化技巧的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/326982.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
iphone基带坏了怎么办
上一篇 2026年11月4日 01:23:43
如何分层管理客户
下一篇 2025年11月15日 12:05:21

相关推荐

  • thinkphp如何避免SQL注入攻击

    一、什么是 SQL 注入攻击 SQL 注入攻击是黑客对网站进行攻击时经常使用的一种手段。SQL注入攻击是指攻击者通过恶意构造的SQL语句,来修改、插入或删除数据库中的数据。在 WEB 应用程序中,大多数情况下以用户输入的参数为基础,开发者未进行有效的过滤和字符转义,使得攻击者可以通过输入恶意字符串获…

    2026年10月28日
    000
  • SQL在MySQL数据库中是如何执行的

    SQL在MySQL数据库中是如何执行的SQL在MySQL数据库中是如何执行的SQL在MySQL数据库中是如何执行的SQL在MySQL数据库中是如何执行的

    今天和mysql视频教程栏目一起看看一条更新语句又是怎么一个执行流程。 查询语句的一套执行流程,更新语句也会同样的走一步,下边我们在对照上次文章中的图来简单的看一下: <img alt=" 首先,在执行语句前要先连接数据库,这是第一步中连接器的工作,前面我们也说过,当一个表有更新的时…

    2026年10月22日 • 用户投稿
    000
  • 如何执行一条SQL更新语句?

    如何执行一条SQL更新语句?如何执行一条SQL更新语句?如何执行一条SQL更新语句?如何执行一条SQL更新语句?

    本篇文章给大家介绍一下执行一条sql更新语句的流程。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 一、前言 前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块。相信你还记得,一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达…

    2026年10月21日 • 用户投稿
    000
  • HTML格式文件怎么导入SQL

    HTML格式文件怎么导入SQLHTML格式文件怎么导入SQLHTML格式文件怎么导入SQLHTML格式文件怎么导入SQL

    导入方法:首先打开软件,打开指定数据库;然后选中要导入数据的数据表,点击鼠标右键,在弹出的菜单中选择“导入向导”;接着导入指定文件,设置目标字段与源字段的对应关系;最后选择一种导入模式,点击“开始”即可。 本教程操作环境:windows7系统、Navicat Premium版本、Dell G3电脑。…

    2026年10月21日 • 用户投稿
    200
  • MySQL运行SQL文件时出现问题怎么办

    MySQL运行SQL文件时出现问题怎么办MySQL运行SQL文件时出现问题怎么办MySQL运行SQL文件时出现问题怎么办MySQL运行SQL文件时出现问题怎么办

    本篇文章给大家介绍一下mysql运行sql文件时出现问题的解决方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 参考:Mysql错误:check the manual that corresponds to your MySQL server version for the r…

    2026年10月21日 • 用户投稿
    1000
  • sql语句中的with as该怎么用

    sql语句中的with as该怎么用sql语句中的with as该怎么用sql语句中的with as该怎么用sql语句中的with as该怎么用

    with as短语,也叫做子查询部分,可以定义一个sql片断,该sql片断会被整个sql语句用到。可以使sql语句的可读性更高,也可以在union all的不同部分,作为提供数据的部分。 –针对一个别名 with tmp as (select * from tb_name) –针对多个别名 with…

    2026年10月20日 • 用户投稿
    000
  • MySQL中怎么使用SQL语句修改数据

    一、修改表中的数据 要更改 MySQL 数据表中的数据,可以使用 UPDATE 语句完成。下面是一个示例: UPDATE students SET name = ‘Tom’ WHERE id = 1; 上面的语句将 students 表中 id 为 1 的记录的 name 字段修改为 “…

    2026年10月14日
    200
  • Linux系统下怎么使用Mysql导入SQL文件

    新建空数据库mysql>create database abc; mysql>create database abc; 导入数据库方法一: 1、选中刚才新建的数据库 mysql>use abc; 2、对数据库进行编码设置 白果AI论文 论文AI生成学术工具,真实文献,免费不限次生成…

    2026年10月14日
    200
  • MySQL调优之SQL查询深度分页问题怎么解决

    MySQL调优之SQL查询深度分页问题怎么解决MySQL调优之SQL查询深度分页问题怎么解决MySQL调优之SQL查询深度分页问题怎么解决MySQL调优之SQL查询深度分页问题怎么解决

    一、问题引入 例如当前存在一张表test_user,然后往这个表里面插入3百万的数据: CREATE TABLE `test_user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ‘主键id’, `user_id` varchar(36) NOT …

    2026年10月14日 • 用户投稿
    100
  • 如何高效构建复杂SQL查询?SprykerSQLCriteriaBuilder助你轻松驾驭动态规则

    在开发电商平台或内容管理系统时,我们经常需要根据用户的选择、后台配置的规则,甚至复杂的业务逻辑来动态生成数据库查询。例如,用户在前端进行多维度筛选(按价格、品牌、类别),或者后台配置复杂的促销规则(满足A条件且B条件,或满足C条件),这些都需要灵活地构建SQL语句。 传统的做法往往是手动拼接sql字…

    2026年10月13日
    200
  • MySQL中sql语句有哪些

    MySQL中sql语句有哪些MySQL中sql语句有哪些MySQL中sql语句有哪些MySQL中sql语句有哪些

    以下两个表格做讲解 SELECT SELECT “字段” FROM “表名”;SELECT Store_Name FROM Store_Info;显示表格中的一个或数个字段的所有数据记录 DISTINCT SELECT DISTINCT “字段” FROM “表名”;select distinct …

    2026年10月12日 • 用户投稿
    200
  • MySQL中怎么使用SQL语句判断表是否存在

    判断表是否存在的SQL语句如下: SHOW TABLES LIKE ‘table_name’; 其中,table_name是要判断是否存在的表的名称。 如果该表存在,则会返回一个结果集,否则将返回一个空结果集。可以通过判断结果集的长度来确定表是否存在。 下面是一个基本的PHP函数,用于在MySQL中…

    2026年10月12日
    100
  • mysql中SQL的概念是什么

    1、SQL是结构化查询语言。 DML 数据操纵语言 用来操作数据库中所包含的数据 INSERT UPDATE DELETE DDL 数据定义语言 用于创建和删除数据库对象等操作 CREATE DROP ALTER DQL 数据查询语言 用来对数据库中的数据进行查询 SELECT DCL 数据控制语言…

    2026年10月12日
    100
  • linux运行sql文件命令是什么

    linux运行sql文件命令是什么linux运行sql文件命令是什么linux运行sql文件命令是什么linux运行sql文件命令是什么

    linux运行sql文件命令是“psql -f test.sql”,其Linux运行sql脚本的方法是:1、使用shell工具登录到安装postgresql的服务器;2、编辑sql脚本内容;3、通过“psql -f test.sql”命令执行“test.sql”脚本即可。 本教程操作环境:linux…

    2026年10月8日 • 用户投稿
    200
  • yii怎么打印sql

    yii怎么打印sqlyii怎么打印sqlyii怎么打印sqlyii怎么打印sql

    想打印Sql的话,可以用把你要执行的命令例如queryAll(),queryOne(),execute()换成getRawSql(); 例如 : 要看 $result = Yii::$app->db->createCommand()->update(‘table’, [‘name’…

    2026年10月3日 • 用户投稿
    100
  • SQL中distinct有什么用法

    SQL中distinct有什么用法SQL中distinct有什么用法SQL中distinct有什么用法SQL中distinct有什么用法

    SQL中distinct的语法是“SELECT DISTINCT column1, column2,…,FROM table_name;”,其中,column1, column2等表示要查询的列名,table_name表示要查询的表名。使用DISTINCT关键字时,SQL会根据指定的列来…

    2026年9月29日 • 用户投稿
    100
  • 如何使用SQL语句在MySQL中进行数据备份和恢复?

    如何使用SQL语句在MySQL中进行数据备份和恢复?如何使用SQL语句在MySQL中进行数据备份和恢复?如何使用SQL语句在MySQL中进行数据备份和恢复?如何使用SQL语句在MySQL中进行数据备份和恢复?

    如何使用SQL语句在MySQL中进行数据备份和恢复? 在数据库中,数据备份和恢复是非常重要的操作,可以保证数据的安全性并且在遇到意外情况时能够迅速恢复数据。MySQL是一个非常常用的关系型数据库,它提供了多种方式来进行数据备份和恢复,其中一种方式就是使用SQL语句。本文将介绍如何使用SQL语句在My…

    2026年9月28日 • 用户投稿
    200
  • SQL中的identity属性是什么意思?

    SQL中的identity属性是什么意思?SQL中的identity属性是什么意思?SQL中的identity属性是什么意思?SQL中的identity属性是什么意思?

    SQL中的Identity是什么,需要具体代码示例 在SQL中,Identity是一种用于生成自增数字的特殊数据类型,它常用于唯一标识表中的每一行数据。Identity列通常与主键列配合使用,可以确保每条记录都有一个独一无二的标识符。本文将详细介绍Identity的使用方式以及一些实际的代码示例。 …

    2026年9月27日 • 用户投稿
    000
  • laravel5如何通过freetds来连接到sqlserver(代码)

    这篇文章给大家介绍的内容是关于laravel5通过freetds连接sqlserver,有一定的参考价值,希望可以帮助到有需要的朋友。 相关版本 系统ubuntu 16.04, 使用的PHP版本是7.0.30, sqlserver 2012, freetds为0.92 Laravel5.5和5.4都…

    2026年9月27日
    300
  • Oracle SQL中除法运算示例

    Oracle SQL中除法运算示例Oracle SQL中除法运算示例Oracle SQL中除法运算示例Oracle SQL中除法运算示例

    标题:Oracle SQL中除法运算示例 在Oracle SQL数据库中,除法运算是常见且重要的运算之一。对于需要对数据进行除法运算的情况,我们可以借助Oracle SQL提供的特定函数和运算符来实现。本文将详细介绍在Oracle SQL中如何进行除法运算,并提供具体的代码示例。 在Oracle S…

    2026年9月26日 • 用户投稿
    100

发表回复

登录后才能评论
关注微信