mysql 判断字段为null表示 false 其它为true_日拱一卒,MySQL数据库 常用SQL优化技巧 十一式...

38559f8a8b9f12421aec300f0739183f.png

本文中所提到的SQL优化技巧均是基于Mysql 索引 BTree类型 。将从以下几个方面介绍常用的SQL优化技巧:

  • 避免在 WHERE 子句中使用 !=<> 操作符。
  • 避免在 WHERE 子句中对索引列使用 %前缀模糊查询
  • 避免在 WHERE 子句中对索引列使用 OR 来连接条件。
  • 避免在 WHERE 子句中对索引列使用 IN NOT IN
  • 避免在 WHERE 子句中对索引列使用计算、函数、类型转换等操作。
  • 避免在 WHERE 子句中对索引列使用参数
  • 使用合理的分页方式以提高分页的效率。
  • 使用 EXISTS 替换 DISTINCT
  • 避免在 WHERE 子句中对索引列进行 NULL 值判断。
  • 避免在 WHERE 子句中对索引列进行 隐式类型转换
  • 合理使用 复合索引

本文篇幅较长 ,建议先收藏再阅读,便于后续查阅。


善用EXPLAIN

通常,我们在写完较为复杂的 SQL 时,一般会进行一下 MySQL 优化,我们要善用 EXPLAIN 查看 SQL 执行计划。

Explain语法

e2745f1f0ac1ebf976e2b76e35475bb5.png

如下

bf90f757b1a33a977436990979bcc34d.png

执行计划包含如下信息:

  • type:连接类型。一般来说,需要保证查询至少达到 range 级别,最好能达到 ref,杜绝出现 all 级别。
  • key:实际使用的索引,如果没有可用的索引,则显示为NULL,可以使用force index强制索引方式。
  • key_len: 索引字段的最大可能长度,理论上长度越短越好,但并非实际使用长度。
  • rows: 表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数,ROWS值的大小是个统计抽样结果,并不十分准确。
  • extra: 额外说明,当出现Using filesort, Using temporary的时候需要注意。

避免在 WHERE 子句中使用 != 或 <> 操作符

应尽量避免在 WHERE 子句中使用 !=<> 操作符,否则将导致引擎放弃使用索引而进行全表扫描。MySQL 只有对以下操作符才会使用索引:,>=,BETWEEN,IN,以及使用 LIKE 时的 后缀模糊查询 %

a1c4eda00c6eea89a02883eb864cfb19.png

避免在WHERE 子句中对索引列使用 %前缀模糊查询

WHERE 子句中使用 LIKE进行模糊查询时,使用 %前缀模糊查询 无法使用索引,从而引发全表扫描。解决 %前缀模糊查询时索引不被使用的方法就是添加覆盖索引(只访问索引的查询,索引和查询列一致,只需扫描索引而无须回表)。

b0241a1405eda8afbcd4c1a2d4fea01d.png

避免在WHERE 子句中对索引列使用 OR 来连接条件

应尽量避免在 WHERE 子句中使用 OR 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描。使用 OR 的字句可以分解成多个查询,并且通过 UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到复合索引,用 UNION ALL 执行的效率更高。

b13b5b1c1f9a590d5dfd212560dc31c1.png

尽量UNION ALL 代替 UNION UNIONUNION ALL 的差异主要是前者需要将结果集合并后再进行唯一性过滤操作,会涉及到排序,增加大量的CPU运算,加大资源消耗及延迟。当然,UNION ALL的前提条件是两个结果集没有重复数据。


避免在WHERE 子句中对索引列使用 IN 和 NOT IN

应尽量避免在 WHERE 子句中使用 IN 和 NOT IN ,否则将导致全表扫描,对于连续的数值,能用 BETWEEN AND 尽量避免使用 IN。一般,用 EXISTS 代替 IN 。若需要使用 IN,在 IN 后面值的列表中,按照值的分布数量降序排列,减少判断的次数。

尝试使用BETWEEN AND 替换 IN 。

0a271b35c1d0520b56592e92a8f55e06.png

我们使用 EXISTS 替代 IN,用 NOT EXISTS 替代 NOT IN,无论在哪种情况下, NOT IN 效率都是最低的。

93f41a442a11385a711f45aadf84ad74.png

尝试使用LEFT JOIN 替换 IN。

4e3a697e27606a39fd55668268fbd6dd.png

如上,我们使用了如下方式优化了 IN NOT IN

  • 使用 between 替换 in ( 如果 in 的条件是连续的)
  • 使用 exists 替代 in、用not exists替代 not in
  • 使用 left join 替换 in

避免在WHERE 子句中对索引列使用计算、函数、类型转换等操作

应尽量避免在 WHERE 子句中对 “=” 左边的字段进行函数、算术运算及其他表达式运算,可以将表达式运算移至“=”右边,否则将导致引擎放弃使用索引而进行全表扫描。

bad36e6328d16b19ca70aa3bb4dc695b.png
6bfcb21c47d92eab5e8fbf1590a0edde.png


避免在WHERE 子句中对索引列使用参数

如果在 WHERE 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时。它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项,可以改为强制查询使用索引。

8e261f6c3fcaa2ee6afbfac6da02739c.png

使用合理的分页方式以提高分页的效率

分页查询在我们的实际应用中非常普遍,也是最容易出问题的查询场景。比如对于下面简单的语句,一般想到的办法是在name,age,register_time字段上创建复合索引。这样条件排序都能有效的利用到索引,性能迅速提升。

18fbb604a9510e7366702dfbef84c0cb.png

如上例子,当 LIMIT 子句变成 “LIMIT 100000, 50” 时,此时我们会发现,只取50条语句为何会这么慢?

原因很简单,MySQL并不知道第 100000条记录从什么地方开始,即使有索引也需要从头计算一次,因此会感觉非常的慢,一般我们在做翻页时,是可以获取上一页中的某个数据标志来缩小查询范围的,比如时间,可以将上一页的最大值时间作为查询条件的一部分,SQL可以优化为这样:

9154d3fedf043503a43be5f9c209eb63.png

使用EXISTS 替换 DISTINCT

EXISTS语句用来判断()内的表达式是否存在返回值,如果存在就返回 True,如果不存在就返回 False,同时它只要括号中的表达式有一个值存在,就立刻返回 True ,而不用遍历表中所有的数据。因此 EXISTS 使查询效率更高。

793101241ebaca6a8496fe134cce4f6f.png

避免在WHERE 子句中对索引列进行 NULL 值判断

应尽量避免在 WHERE 子句中对字段进行 NULL 值判断,否则将导致引擎放弃使用索引而进行全表扫描,创建表时 NULL 是默认值,但大多数时候应该使用 NOT NULL,或者使用一个默认值,如 0 作为默认值。

例如,性别,使用1表示男,2表示女,0表示未知或者是用户没有选择,默认值设置为 0,因为大部分编程语言的数字类型的默认值0。

ac3e3dad7a5567a74f731bd237fff949.png

空值和NULL是有区别的,以一个杯子为例:

  • 空值 代表杯子是真空的。
  • NULL 代表杯子中装满了空气。

如果字段允许为空,可能会有以下问题:

  • 查询条件就必须处理为空的情况,否则会出现一些很奇怪的问题,比如 NOT IN、!= 等负向条件查询在有 NULL 值的情况下返回永远为空结果,查询容易出错。
  • 在部分数据库中会导致索引失效
  • 可空列需要更多的存储空间,导致空间变大,进而导致数据库系统查询分析变的复杂。
  • 在程序中也需要每次都判断是不是空,导致程序复杂了。

但凡事没有绝对的,使用默认值的思路可以解决很大一部分可为空的问题,但不是所有都需这样做,具体还是要根据具体业务进行分析。


避免在WHERE 子句中对索引列进行隐式类型转换

当我们对不同类型的值进行比较的时候,为了使得这些数值可比较,MySQL会做一些隐式转化(Implicit type conversion)。

SQL查询语句的条件中字段赋值与字段定义类型不匹配是一种常见的错误用法。

88232acd665d4501b0987aabafcff979.png

如上,字段 account 的定义为 varchar 类型,在 WHERE 条件中 account 字段是数字型,两者数据类型不一样,这时是没法直接进行比较的,需要进行类型转换。MySQL的策略是将表中 account 字段全部转换为数字型之后再比较,由于函数作用于表字段,引起索引失效,导致全表扫描,正确的写法如下:

efbf36021b0437259e40997cbcb08dc2.png

合理使用复合索引

69d1fc39d0ac91edf75ee076a806670c.png

如果经常执行如上查询,那么建立三个单独索引 不如建立一个复合索引,因为三个单独索引通常数据库每次执行只能使用其中一个,虽然这样比不使用索引而进行全表扫描提高了很多效率,但使用复合索引因为索引本身就对应到三个字段上的,效率会有更大提高。

那么为什么数据库只支持一条查询语句只使用一个索引,简单的讲是因为N个独立索引同时在一条语句使用的效果比只使用一个索引还要慢,开销太大

在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

同时,复合索引的生效原则是从前往后依次使用生效,如果中间某个索引没有使用,那么断点前面的索引部分起作用,断点后面的索引没有起作用,造成断点的原因一般有:

  • 前边的任意一个索引没有参与查询,后面的不生效。
  • 前边的任意一个索引失效,当前索引及后面全部不生效。
  • 前边的任意一个索引字段参与的是范围查询,后面的不生效。

引发索引失效,导致全表扫描的原因有:

  • 索引列进行计算、函数、类型转换等操作。
  • 索引列使用不等于,如 != <>
  • 索引列使用 IS NULL ,IS NOT NULL
  • 模糊查询LIKE 以通配符开头如,%str
  • 索引列使用使用 OR 来连接条件。
  • 索引列使用 NOT IN
  • 类型错误,如字段 NUM 类型 为varcharWHERE 条件用 numberNUM = 1
  • WHERE子句和 ORDER BY使用相同的索引,并且 ORDER BY的顺序和索引顺序相同,并且 ORDER BY 的字段都是升序或者降序,否则不会使用索引。
  • 复合索引不符合最佳左前缀原则或存在断点
  • 如果MYSQL评估使用索引比全表扫描更慢,则不使用索引。

例如我们建立了一个这样复合索引key index (col1, col2, col3),那么其实相当于创建了(col1),(col1, col2),(col1, col2, col3) 三个索引,即最佳左前缀特性。

f7eb1ed62069d006ebb28c8982728fcc.png

其他 优化 技巧

当索引列有大量数据重复时,SQL查询可能不会去利用索引,并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的。如表中有“性别”字段,即使在“性别”字段建立索引也对查询效率起不了作用,尽量不要对数据库中某个含有大量重复的值的字段建立索引。


建立索引可以提高 SELECT 的效率,但 索引并不是越多越好。索引同时也降低了 INSERT 及 UPDATE 的效率,因为 INSERT 或 UPDATE 时有可能会重建索引,所以怎样建索引需要慎重考虑,视实际应用情况而定。同时,一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用的字段是否有建立索引的必要。


对于数值字段,尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言,只需要比较一次就够了。

对于字符型字段,尽量的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。


避免使用 select * from table,用具体的字段列表代替“*”,避免返回用不到的任何字段。


尽可能的使用索引字段作为查询条件,尤其是聚簇索引,必要时可以通过index index_name来强制指定索引,避免对大表查询时进行table scan,必要时考虑新建索引。要注意索引的维护,周期性重建索引,重新编译存储过程。


在新建临时表时,如果一次性插入数据量很大,那么可以使用 SELECT INTO 代替 CREAT TABLE,避免造成产生大量日志 ,以提高速度。如果数据量不大,为了缓和系统表的资源,应先CREAT TABLE,然后INSERT。


当服务器的内存够多时,配置 线程数量 = 最大连接数 + 5,使其发挥最大的效率。否则使用配置 线程数量 < 最大连接数启用SQL SERVER的线程池来解决,如果还是 线程数量 = 最大连接数+5,可能会严重的损害服务器的性能。


尽量避免向客户端返回大量结果数据,若数据量过大,应该考虑相应需求是否合理。尽量避免大事务操作,提高系统并发能力。


创建索引的一般规则

  • 表的主键、外键需要建立索引。
  • 频繁与其他表进行连接的表,在连接字段上应该建立索引。
  • 频繁出现在 WHERE 子句及 ORDER BY 中的字段,特别是大表的字段,应该建立索引。
  • 索引应该建在短字段上,对于大的文本字段甚至超长字段,避免建索引。
  • 复合索引的建立需要结合实际应用进行分析,尽量考虑用单字段索引代替。
  • 正确选择复合索引中的主列字段,一般是选择性较好的字段;
  • 复合索引的几个字段是否经常同时以 AND 方式出现在 WHERE 子句中,单字段查询是否极少甚至没有,如果是,则可以建立复合索引,否则考虑单字段索引。
  • 如果复合索引中包含的字段经常单独出现在 WHERE 子句中,则分解为多个单字段索引。
  • 如果复合索引所包含的字段超过3个,需要结合实际应用考虑其必要性,考虑减少复合的字段。
  • 如果既有单字段索引,又有这几个字段上的复合索引,通常可以删除复合索引。
  • 频繁进行数据操作的表,不要建立太多的索引,删除无用的索引。
  • 建立的每个索引都会增加存储开销,索引对于插入、删除、更新操作也会增加处理上的开销。另外,过多的复合索引,在有单字段索引的情况下,一般都是没有存在价值的。相反,还会降低数据增加删除时的性能,特别是对频繁更新的表来说,负面影响非常大。
  • 尽量不要对数据库中某个含有大量重复的值的字段建立索引。
409e635ce86d429ca6bfabe77d56f6db.png

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字图像处理

题目&#xff1a;大规模图像中的目标检测与分类方法 在进行图像目标识别与跟踪时&#xff0c;摄像机所采集的图像&#xff0c;在成像、数字化以及传输过程中&#xff0c;难免会受到各种各样噪声的干扰&#xff0c;图像的质量往往会出现不尽人意的退化&#xff0c;影响了图像的视…

内容可编辑_让PDF像WORD一样自由编辑,好用的PDF编辑工具推荐

在日常工作中&#xff0c;我们经常要和PDF文件打交道。以往编辑PDF文件&#xff0c;比如修改文字等&#xff0c;需要下载专门的PDF编辑软件&#xff0c;通常编辑器都会超过200M&#xff0c;下载安装很麻烦&#xff0c;还会挤压电脑的储存空间&#xff0c;影响运行速度。当迅读P…

会返回两次_嫦娥五号为何用独特的半弹道式返回方式?原来有更深远的考虑……...

更多战史及装备评说&#xff0c;请移步公众号asiavikin&#xff08;转载请注明出处&#xff09;24日凌晨4时30分&#xff0c;嫦娥五号在文昌航天发射场由长征五号火箭成功送入地月转移轨道&#xff0c;22时6分完成第一次轨道修正&#xff0c;可喜可贺。这是人类44年来首度去月球…

【转】VS2013中如何解决error C4996: 'fopen'问题

原文网址&#xff1a;http://jingyan.baidu.com/article/ce436649fd61543773afd32e.html 今天编写控制台应用程序时出现如下错误 error C4996: fopen: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_…

中关键字 表示空类型_C语言数据类型

程序在运行时要做的内容就是处理数据。程序要解决复杂的问题&#xff0c;就要处理不同的数据。不同的数据都是以自己本身的一种特定形式存在的&#xff0c;不同的数据类型占用不同的存储空间。C语言中有多种不同的数据类型&#xff0c;其中包括几个大的方向&#xff1a;基本数据…

理解inode

。 理解inode 一、inode是什么&#xff1f; 理解inode&#xff0c;要从文件储存说起。 文件储存在硬盘上&#xff0c;硬盘的最小存储单位叫做"扇区"&#xff08;Sector&#xff09;。每个扇区储存512字节&#xff08;相当于0.5KB&#xff09;。 操作系统读取硬盘的时…

帧同步_微信小游戏接入“熊孩子噩梦”健康系统 帧同步能力上线

3月31日&#xff0c;微信小游戏官方公众号“做个小游戏”发文宣布全新面向未成年人保护的健康系统已经上线&#xff0c;该系统联动“成长守护平台”的功能&#xff0c;可以更好助力家长群体对于未成年人游戏行为的监管。另外就在昨天&#xff0c;微信小游戏也曝光了另外一项新能…

Myeclipse 安装Aptana3.2 插件

转自&#xff08;http://www.cnblogs.com/yinger/archive/2011/08/29/2157193.html&#xff09; 安装步骤&#xff1a; 1、下载aptana3.2 Eclipse Plugin插件. 下载地址&#xff1a;http://update1.aptana.org/studio/3.2/024747/index.html 2、在java文件夹下新建文件夹plugin…

Linux系统初级优化

系统参数优化和怎样增强系统安全性&#xff0c;系统默认的一些参数都是比较保守的&#xff0c;所以我们可以通过调整系统参数来提高系统内存、CPU、内核资源的占用&#xff0c;通过禁用不必要的服务、端口&#xff0c;来提高系统的安全性&#xff0c;更好的发挥系统的可用性。通…

【原创】SQlServer数据库生成简单的说明文档小工具(附源码)

这是一款简单的数据库文档生成工具&#xff0c;主要实现了SQlServer生成说明文档的小工具&#xff0c;目前不够完善&#xff0c;主要可以把数据库的表以及表的详细字段信息&#xff0c;导出到Word中&#xff0c;可以方便开发人员了解数据库的信息或写技术说明文档。技术上主要采…

封装成vla函数_第四章:Python之函数

第一节&#xff1a;函数入门与定义函数理解函数所谓函数&#xff0c;就是为一段实现特定功能的代码“取”个名字&#xff0c;以后即可通过该名字来执行(调用)这段代码从逻辑上看&#xff0c;函数相当于一个黑匣子定义函数的语法定义函数的三条铁律函数需要几个关键的、需要动态…

allegro大十字光标设置方法

使用大十字光标&#xff0c;在摆放元器件时&#xff0c;容易对齐。在allegro中&#xff0c;可以通过设置实现大十字光标&#xff0c;其具体方法如下&#xff1a; &#xff11;、选择Setup->User Perferences,即可出现如下图所示界面&#xff1a; &#xff12;、选择Display-…

基于.NET平台常用的框架整理(收藏)

目录 分布式缓存框架 日志记录异常处理 关于NoSQL数据库 自动任务调度框架 依赖注入IOC容器框架 常用的几个ORM框架 格式和数据类型转换 反射和动态语言 跨平台和运行时解决方案 WEB开发和设计 移动互联网和云计算 网络通信和网络协议 图形和图像处理框架 桌面应用程序框架 测试…

界址点号_界址点及四至优化

先对文中提到的面做一个解释&#xff0c;他可以指地块&#xff0c;宗地。一、界址点先说一下对界址点优化的情况&#xff0c;之前的方法主要是只要考虑了对坐标排序的问题&#xff0c;对于比较规整的面出的效果还是挺好&#xff0c;但往往现实中的面都比较复杂&#xff0c;像下…

java程序 输入10个数字并求和

课程作业&#xff1a; 模仿JavaAppArguments.java示例&#xff0c;编写编写一个程序&#xff0c;此程序从命令行接受多个数字&#xff0c;求和之后输出结果。 设计思想&#xff1a; 先从命令行读出数字&#xff0c;然后计算各个数字之和。求出结果。 流程图&#xff1a; 程序源…

是先打工还是直接创业?答案让我惊呆了!

第一问&#xff1a;成功路上&#xff0c;您是自己乱走&#xff0c;还是有老师指导更好&#xff1f;人生路上&#xff0c;因为有父母&#xff0c;才有生命&#xff1b;成功路上&#xff0c;因为有老师&#xff0c;才有方向。父母优秀&#xff0c;才可以培养出优秀的孩子。优秀的…

MVC知识点整理汇总

MVC与ASP.NET MVC基础概念MVC是Model-View-Controller的缩写.MVC将应用程序划分为3大组件:模型\视图\控制器.MVC不是ASP.NET所特有,它只是一种开发理念.java中的struts2也是一种MVC模型.ASP.NET MVC从2008年发布1.0版以来,截至2014年ASP.NET MVC最新版本已经是5.0.ASP.NET MVC从…

第三次作业——结对编程

成员&#xff1a;031302439 031302415 本次实践中我们是用phpmysql来实现所需功能的&#xff0c;其中使用到的软件有PowerDesigner和WampServer 一. PowerDesigner使用过程 1. 运行程序&#xff0c;进入主界面&#xff0c;新建一个Model&#xff0c;设置DBMS属性。我们…

NET比较常用的性能优化技巧

现在很多客户也慢慢开始注重网站的性能了&#xff0c;同时有很多运营网站的公司也不像以前那样特别在意网站是否非常漂亮&#xff0c;而把更多的精力放在了网站性能优化上面&#xff0c;提供更快更稳定的浏览速度&#xff0c;在这个基础上面进行网站功能上的扩充和完善&#xf…

js修改mysql数据库数据_Node.js操作mysql数据库增删改查

关于node.js操作mysql数据库的相关介绍请阅读全文吧。下文介绍的非常详细&#xff0c;具体内容如下所示&#xff1a;安装mysql模块npm install mysql数据库准备mysql server所在的机器IP地址是192.168.0.108&#xff0c;登录账户就用root123456在mysql中创建test数据库在test数…