MySql(五)之sql优化

2023-05-16

##概述

作为一个高级程序员,不仅要熟练使用sql语句,更应该使用高效的sql语句。

本篇blog讲解的内容主要包括:

  1. 索引的使用。
  2. 执行计划分析。
  3. sql优化常见案例分析。

##索引

一,什么是索引

索引的作用只有一个,提高查找效率。

如下面sql语句:

select name from person where age = 16;

在正常情况下,MySql是从第一条数依次遍历,直到读完整个表才能得到所有age等于16的数据。

如果对age字段建立索引,MySql会维护一个索引表,索引表中存储不同age与数据对对应关系,当查找age等于16的数据时会先在索引表中找到age等于16对应的数据id,然后直接根据数据id从数据表中需要的数据。这就类似于新华字典中的拼音查字法,先从拼音序列中找出这个字在哪一页,然后直接去那一页去找,避免翻遍整个字典,很大的提供了查找效率。

 

二,索引的利弊分析

上面说到创建索引会很大的提高查找效率,但索引也有弊端。

创建索引系统会自动维护一个索引表,每当数据增加,更新,删除时都需要更改索引表,所以创建索引会降低增加,更新,删除的效率。

三,创建索引的原则

创建索引针对的对象是字段,所以我们要找出适合创建索引的字段。

建议创建索引的列:

  1. 定义主键的数据列一定要建立索引。
  2. 定义有外键的数据列一定要建立索引。
  3. 对于经常查询的数据列最好建立索引。
  4. 对于需要在指定范围内的快速或频繁查询的数据列最好创建索引;
  5. 经常用在WHERE句中的数据列最好创建索引。
  6. 经常出现在关键字order by、group by、distinct后面的字段,建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致,否则索引不会被使用。

不建议创建索引的列:

  1. 对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。
  2. 对于定义为text、image和bit的数据类型的列不要建立索引。
  3. 对于经常存取的列避免建立索引 
  4. 限制表上的索引数目。对一个存在大量更新操作的表,所建索引的数目一般不要超过3个,最多不要超过5个。索引虽说提高了访问速度,但太多索引会影响数据的更新操作。
  5. 对复合索引,按照字段在查询条件中出现的频度建立索引。在复合索引中,记录首先按照第一个字段排序。对于在第一个字段上取值相同的记录,系统再按照第二个字段的取值排序,以此类推。因此只有复合索引的第一个字段出现在查询条件中,该索引才可能被使用,因此将应用频度高的字段,放置在复合索引的前面,会使系统最大可能地使用此索引,发挥索引的作用。

注:具体怎么哪些列可以创建索引,哪些列不建议创建索引,需要具体情况具体分析,需要开发中慢慢积累经验。

四,创建索引

索引分为单索引和组合索引。但索引是给一个字段创建的索引,组合索引是给多个字段创建的索引。

比如给person表中的age字段创建索引的sql是:

ALTER TABLE `xia`.`person` ADD INDEX(`age`) USING BTREE COMMENT '给age创建索引';

navicate也支持创建索引的图形化操作,如下:

 

##执行计划

执行计划就是分析执行某个sql语句的详细细节。

查看某个sql语句的执行计划很容易,只有在sql语句前添加EXPLAIN关键词即可。如下:

EXPLAIN select  * from person WHERE age = 16 and id > 0;

执行结果如下:

说明:

  1. type:表示执行sql使用了哪种类型。类型的种类从好到差依次是:const、eq_reg、ref、range、indexhe和ALL。
  2. possible_keys:可能使用到的索引。此时有两个:PRIMARY,index_age。其中PRIMARY是主键,index_age是自己创建的索引。
  3. key:实际用到的索引。
  4. key_len:使用索引的长度,该值越小越好。
  5. ref:
  6. rows:数据遍历的行数,数值越小越好。

总结:要学会且有意识的多使用执行计划,查看每一个sql语句的执行计划,尽量优化sql,提高项目的执行效率。

 

##sql优化具体分析

sql优化主要针对查询sql进行优化,因为只有查询语句才会出现扫描全表的情况。随着数据量的增大,扫描全表会非常耗时,优化sql的目的是尽量扫描少的数据量。

具体细节如下:

1,尽量给字段设置默认值,避免字段值为null情况。

如果字段是int类型的age,首先给age创建索引时null不会参与创建索引。where age=0比where age is null效率高。

 

2,在where语句中少使用or,使用or将不使用索引。

如select name where age = 16 or age = 20

可以写成:

select name where age = 16 union all select name where age = 20

 

3,在where语句中避免使用in,

如select * from score where student_id in (select id from student where name='guoxiang')

可以写成:

select * from score sc  where exists (select 1 from student st  where st.name='guoxiang' and st.id = sc.student_id)

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySql(五)之sql优化 的相关文章

  • Delphi XE5 FireDAC 错误:无法加载供应商库 [libmysql.dll 或 libmysqld.dll]

    我在 Windows 7 64 位上使用 Delphi XE5 只是尝试 FireDAC 组件 我正在使用一个 TFDConnection 组件连接到本地 MySQL 数据库 v5 6 15 我已经将 libmysql dll 32位 v5
  • Oracle中如何选择前100行?

    我的要求是获取每个客户的最新订单 然后获取前100条记录 我编写了一个如下查询来获取每个客户的最新订单 内部查询工作正常 但我不知道如何根据结果获得前 100 名 SELECT FROM SELECT id client id ROW NU
  • 随机排列每行的列值

    我正在使用 C NET 开发多项选择题考试生成器 每次做出报告时 都会在数据库中随机挑选问题 并随机调整选项 我可以做随机问题部分 但我不能做选择的洗牌 我有一张表 其中一行如下 question answer distractor1 di
  • DBX 错误:驱动程序无法正确初始化

    我在跑步德尔福XE3 终极版 MySQL 数据库 这是我点击时收到的错误Test Connection 作为回应 我在 xampp 目录中找到了 libmysql 库 并将其复制到我的 System32 目录中 但这是行不通的 此消息指的是
  • JbdcTemplate - 带有动态 SQL 查询的PreparedStatements

    I know jdbcTemplate可以用来创建PreparedStatements如果你这样设置 i e private JdbcTemplate jdbcTemplate String sqlQuery Select from tab
  • 如何从连接字符串中提取数据库名称,而不考虑 RDBMS?

    我正在研究一个不知道正在使用的 RDBMS 的课程 当然 应用程序的其余部分都清楚这一点 连接字符串是此类的输入 我需要数据库名称 无论 RDBMS 如何 如何从连接字符串中提取数据库名称 我读到以下问题 如何使用 SqlConnectio
  • Symfony/Doctrine 重新排列数据库列

    当我使用doctrine schema update命令行生成表时 Doctrine 或Symfony 似乎想要添加一个命令来重新排列我的列 将键放在它出现的前面 我想知道是否 更希望在哪里 我可以禁用环境的这个 功能 所以当我去生成我的表
  • PostgreSQL & regexp_split_to_array + 取消嵌套

    我有这样的绳子 测试1 纽约 X 测试 2 芝加哥 Y 测试 3 宾夕法尼亚州哈里斯堡 Z 我需要的结果是 Column1 Column 2 Column3 Test 1 new york X Test 2 chicago Y Test 3
  • Python 子进程、mysqldump 和管道

    我在尝试构建简单的备份 升级数据库脚本时遇到问题 错误出现在使用子进程的 mysqldump 调用中 cmdL mysqldump user db user password db pass domaindb gzip gt databas
  • SQL Like 带有子查询

    我怎样才能做到这一点 SELECT FROM item WHERE item name LIKE SELECT equipment type FROM equipment type GROUP BY equipment type 内部子查询
  • 将我的 Laravel 连接到外部数据库

    如何将 Laravel 连接到外部数据库 示例 我的本地计算机上有一个 Laravel 它在 xampp 上运行 我希望它连接到云服务器数据库 打开 env文件并编辑它 只需设置正确的外部数据库凭据 DB CONNECTION mysql
  • 如何在 MySQL 中启用严格 sql_mode?

    我怎样才能启用严格sql mode在 MySQL 中 我想从 SQL 中获取数据并在中处理相同的数据strict mode 我现在的sql mode is mysql gt SELECT sql mode sql mode NO ENGIN
  • MySQL - 从另一个表插入与常量合并的数据

    我有一个包含一些数据的临时表 products temp 并且我有另一个需要将数据插入其中的表 产品 我需要在新记录上手动设置一些常量 例如vendor id 1等 是否可以在一次请求中插入临时表数据和常量 临时产品 product nam
  • Sql批量复制截断小数

    当我使用批量复制将十进制值从 C DataTable 插入 Sql Server 2005 时 值会被截断而不是四舍五入 DataTable 中的数据类型为 Decimal 数据库中的数据类型为Decimal 19 3 数据表中的值为 1
  • 常量值如何影响连接的 ON 子句?

    我最近发现 LEFT JOIN 的 ON 子句可能包含 1 1 等值 这让我感到不安 因为它打破了我对连接功能的看法 我遇到过以下情况的更详细版本 SELECT DISTINCT Person ID FROM Person LEFT JOI
  • 当php脚本通过ajax运行时显示进度条

    我有一个通过 ajax 向服务器提交值的表单
  • ActiveRecord 查询,按关联排序,最后一个 has_many

    我试图列出所有Users by the created at最近创建的关联记录 通讯 列 到目前为止我所拥有的 User includes communications order communications created at IS
  • SQL Server 标识列值从 0 而不是 1 开始

    我遇到了一个奇怪的情况 数据库中的某些表的 ID 从 0 开始 即使 TABLE CREATE 的 IDENTITY 1 1 也是如此 对于某些表来说是这样 但对于其他表则不然 它一直有效到今天 我尝试过重置身份列 DBCC CHECKID
  • Yii2:无法将列值更新+1

    创建新记录时 我需要将列值更新 1 public function actionCreate model new CreateBookings if model gt load Yii app gt request gt post Yii
  • 在 Django shell 会话期间获取 SQL 查询计数

    有没有办法打印 Django ORM 在 Django shell 会话期间执行的原始 SQL 查询的数量 Django 调试工具栏已经提供了此类信息 例如 5 QUERIES in 5 83MS但如何从 shell 中获取它并不明显 您可

随机推荐

  • C++ 错误解决 —— internal compiler error

    问题 xff1a g 43 43 编译时 xff0c 报错 xff1a g 43 43 internal compiler error Killed program cc1plus 出错原因 xff1a 出错的原因是 xff08 虚拟机 x
  • 基于STC89C52的智能小车——红外避障篇

    做这个小车真是历尽波折 因为我的零件是散买的 xff0c 所以在组装时出了各种幺蛾子 先是装马达的时候发现螺丝买短了 xff0c 之后又是单片机最小单元装不到小车底板上 千辛万苦把小车组装好了 xff0c 终于可以开心 xff08 并不 x
  • make、makefile、cmake之间的区别与联系

    make makefile cmake之间的区别与联系 首先说明一下make makefile cmake存在的原因 在进行编译时 xff0c 如果程序只有一个源文件 xff0c 那么我们可以直接利用gcc命令对其进行编译 xff1b 但是
  • 基于STC89C52的智能小车——PWM调速篇

    虽然我的小车因为电池电压太低慢的要死 xff0c 不过PWM还是要学的 PWM简单来说就是通过调整占空比 xff08 一个时间段 t 内电机运行的时间占总时间的比例 xff09 来调整小车速度 当然为了小车运行稳定 t 必须很小 xff0c
  • 基于STC89C52的智能小车——红外避障+PWM调速篇

    这篇学习笔记虽然看起来很水 xff0c 毕竟红外避障和PWM在之前的学习笔记里都写过了 xff0c 但这次确实是我耗时最久的一次作业 用软件实现PWM真是一个深渊巨坑 首先是由于小车的方向函数的运作方式是切换运动状态 xff0c 而我们用P
  • 基于STC89C52的智能小车——蓝牙遥控篇

    蓝牙遥控是依靠单片机的串口通讯来实现的功能 这周我主要学习的内容是串口通讯 在完成学习后我用之前买避障小车时顺便买的蓝牙模块做了一个升级版智能小车 xff0c 它可以通过蓝牙模块实现避障模式与蓝牙遥控模式的切换以及速度的调整 蓝牙模块的接线
  • DS1302实时时钟

    DS1302是一款可离线运转的实时时钟 本周我的学习任务是利用它和LCD1602来在学习板上制作一个时钟 下面是代码 xff08 除LCD1602的头文件 xff09 main span class token macro property
  • 利用矩阵键盘制作密码锁

    本周学习了关于矩阵键盘的知识 xff0c 并利用矩阵键盘制作了密码锁 矩阵键盘利用矩阵式的连接减少了IO口的使用 xff0c 并用扫描的方式保证每一个按键的响应 下面是代码 main span class token macro prope
  • LED点阵

    本周的学习内容是LED点阵的使用 其实LED点阵与动态数码管的原理非常相似 xff0c 都是通过扫描和视觉暂停现象来实现多个LED同时点亮的视觉效果 不同的是 xff0c 点阵可以通过74HC595来实现三根线串行输入多根线并行输出的效果
  • 前端进度条动画(自定义颜色)

    前端进度条动画 xff08 自定义 代码如下 xff08 示例 xff09 xff1a span class token operator lt span template span class token operator gt span
  • Keil调试中遇到问题汇总

    1 Keil MDK中工程编译弹出提醒框 xff1a Browse information of one of more files is not available Doing a project rebuild might fix th
  • C语言实现TCP服务器与客户端通信

    以上是TCP通信客户端与服务器实现通信的基本原理流程图 1 客户端的实现 xff08 4个步骤 xff09 1 1创建socket对象 1 2请求连接 1 3发送数据 1 4关闭套接字 include lt stdio h gt inclu
  • 关闭select监控的fd出现的问题及解决方案

    关闭select监控的fd出现的问题及解决方案 前言一 实现思路二 问题三 bind 失败分析1 使用netstat查看socket状态2 为什么srv fd引用计数会加13 select 超时后srv fd引用计数减14 man sele
  • SVN如何打tag,以及主干,分支的相互合并操作

    1 给项目打 tag的步骤 1 xff09 选中项目后 xff0c 点击鼠标的左键弹出对话框 选择TortoiseSVN gt Branch tag 如图所示 点击Branch tag后弹出如下对话框 svn 显示的路径是需要打tag文件的
  • OKHttp使用详解

    一 xff0c OKHttp介绍 okhttp是一个第三方类库 xff0c 用于android中请求网络 这是一个开源项目 是安卓端最火热的轻量级框架 由移动支付Square公司贡献 该公司还贡献了Picasso和LeakCanary 用于
  • HttpUrlConnection使用详解

    一 xff0c HttpURLconnection的介绍 在Android开发中网络请求是最常用的操作之一 xff0c Android SDK中对HTTP 超文本传输协议 也提供了很好的支持 xff0c 这里包括两种接口 1 标准Java接
  • SwipeRefreshLayout的使用详解

    一 xff0c 概述 SwipeRefreshLayout意思为下拉刷新的布局 xff0c 其继承ViewGroup xff0c Google在android5 0中提供的下拉刷新控件 xff0c 且提供了v4支持包 这是一个容器布局 xf
  • Java操作数据库方式(六)DataSource详解

    概述 在java世界里操作数据库有很多方式 xff0c 在众多方式中除了JDBC外都有DataSource对象 DataSource可以看作数据源 xff0c 它封装了数据库参数 xff0c 连接数据库 xff0c 程序中操作DataSou
  • MySql(四)之项目实战

    概述 MySql项目实战是结合实际开发工作 xff0c 来说明数据库分析 xff0c 数据库设计 xff0c 数据库创建等一些列流程 这部分知识不属于严谨的技术 xff0c 不同的人有不同的方法 xff0c 如果你不认可你可以继续自己的方法
  • MySql(五)之sql优化

    概述 作为一个高级程序员 xff0c 不仅要熟练使用sql语句 xff0c 更应该使用高效的sql语句 本篇blog讲解的内容主要包括 xff1a 索引的使用 执行计划分析 sql优化常见案例分析 索引 一 xff0c 什么是索引 索引的作