SQL优化的方法

news2024/11/26 2:22:02

(1)建立物化视图或尽可能减少多表查询。

(2)以不相干子查询替代相干子查询。

(3)只检索需要的列。

(4)用带in的条件子句等价替换or子句。

(5)经常提交commit,以尽早释放锁。

(6)避免嵌套的游标(Cursor)和多重循环等。

(7)在经常查询的列上创建索引,提高查询效率。

(8)避免使用模糊查询进行匹配,如果一定要使用,建议使用最左模糊匹配原则。

(9)慢的查询的sql,根据性能和存储容量大小进行评估,适当的可以考虑水平分表和垂直分表,以提高sql的查询性能。

(10)查询数据是否存在,适当的可以使用exists替代in。

建表

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

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

临时表

  1. 避免频繁创建和删除临时表,以减少系统表资源的消耗
  2. 尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。
  3. 临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
  4. 在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log,以提高速度;
  5. 如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
  6. 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table,然后 drop table,这样可以避免系统表的较长时间锁定。

游标的问题

  1. 尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。游标的一个常见用途就是保存查询结果,以便以后使用。游标的结果集是由SELECT语句产生,如果处理过程需要重复使用一个记录集,那么创建一次游标而重复使用若干次,比重复查询数据库要快的多。
  2. 使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
  3. 与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

事务

尽量避免大事务操作,提高系统并发能力。

数据量问题

13.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

具体SQL优化 

1.避免使用select *

select *不走覆盖索引,会有大量的回表操作,从而导致查询SQL的性能很低。应该使用具体的字段代替*,只返回使用到的字段。     

2.用union all代替union

union可以获取排除重复后的数据,union all可以获取所有数据,包含重复的数据,排除重复的过程需要遍历,排序和比较,他更耗时,更消耗CPU资源,所以如果能用union all,尽量不用union,除非是业务场景中不允许产生重复数据

3.小表驱动大表

in 和 not in 也要慎用,否则会导致全表扫描。对于连续的数值,能用 between 就不要用 in,对于子查询,可以用exists代替。

用小表的数据集驱动大表的数据集

in关键字,他会优先执行in里面的子查询语句,然后在执行in外面的语句,in里面的数据量很少,作为条件查询速度更快

exists关键字,他会优先执行exists左边的语句(即主查询语句),然后把它作为条件,去跟右边的语句匹配,如果匹配上,则可以查出数据,如果匹配不上,数据就被过滤掉了

in适用于左边大表,右边小表

exists适用于左边小表,右边大表

4.批量操作

每次远程请求数据库,是会消耗一定性能的

提供一个批量插入的方法,这样只需要远程请求一次数据库,SQL性能会提升,数据量越大,提升越多,但是不建议一次批量操作太多数据,如果数据太多,数据库响应也会很慢,批量操作需要把握一个度,建议每批数据尽量控制在500以内,多批如果数据多于500,则分多批处理。

5.多用limit

6.in中值太多

如果in数据太多,不做任何限制,可能会导致接口超时

可以在SQL语句中对数据用limit做限制,不过更多的是在业务代码中加限制

如果超出500,可以分批用多线程去查询数据,每批只查500条记录,最后把查询到的数据汇总到一起返回

7.增量查询

有时候,我们需要通过远程接口查询数据,然后同步到另一个数据库,如果直接获取所有的数据,然后同步过去,这样如果数据很多,查询性能会非常差,可以按时间和id升序,每次只同步一批数据,这一批数据只有100条记录,每次同步完后,保存这100条数据中最大的id和时间,给同步下一批数据的时候用,通过这种增量查询的方式,能够提升单次查询的效率

select * from user where id > #{lastId} and create_time >= #{lastCreateTime} limit 100;

8.高效的分页

列表页在查询数据的时候,为了避免一次性返回过多的数据影响接口性能,我们一般会对查询接口做分页处理,在数据库中分页一般用的limit关键字如图

select id,name,age from user limit 10,20;

如果表中的数据量较少,用limit关键字做分页,没什么问题,但如果表中数据量很多,用他就会出现性能问题,

select id,name,age from user limit 1000000,20;

优化

select id,name,age from user where id >1000000 limit 20;

利用id上的索引查询,要求id是连续的,并且是有序的,还可以使用between优化分页

select id,name,age from user where id between 1000000 and  1000020;

between要在唯一索引上分页,不然会出现每页大小不一致的问题

9.用连接查询代替子查询

数据库中如果需要从两张以上的表中查询出数据的话,一般有两种方式,子查询和连接查询

子查询,可以通过in关键字实现,一个查询语句的条件落在另一个select语句的查询结果中,程序先运行嵌套在最内层的语句,在运行外层的语句,子查询的优点是简单,结构化,如果涉及的表数据不多的话,但缺点是数据库执行子查询时,需要创建临时表,查询完毕后,会删除这些临时表,有一些额外的性能消耗

select * from order where user_id in (select id from user where status=1);

连接查询,性能会更高

select o.* from order o
inner join user u on o.user_id=u.id
where u.status=1;

10.join的表不宜过多

join表的数据不应超过3个,如果join太多,数据库在选择索引的时候会非常复杂,很容易选错索引,并且如果每天命中,nested loop join就是分别从两个表读一行数据进行两两对比

11.join时要注意

我们在使用多张表联合查询的时候,一般会使用join关键字,join使用最多的是是left join和inner join

left join求两个表的交集外加左表剩下的数据

inner join求两个表交集的数据

12.索引

        并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

        索引问题 法则:不要在建立的索引的数据列上进行下列操作:避免对索引字段进行计算操作。避免在索引字段上使用not,<>,!=。避免在索引列上使用IS NULL和IS NOT NULL。避免在索引列上出现数据类型转换。避免在索引字段上使用函数。避免建立索引的列中使用空值。

        索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率 因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要

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

控制索引的数量:索引可以显著提升 查询的性能,但索引数量并非越多越好,因为表中新增数据时,需要同时为他创建索引,而索引时需要额外的存储空间的,而且还会有一定的性能消耗,单表中的索引数量应该尽量控制在5个以内,并且单个索引中的字段不超过5个

13.合理的数据类型

14.提升group by的效率

select user_id,user_name from order group by user_id having user_id <=200;

优化

select user_id,user_name from order where user_id <=200 group by user_id;

15,索引优化

检查SQL语句有没有走索引-explain查看数据库的执行计划

 

16.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

where 表之间的连接必须写在其他 Where 条件之前, 那些可以过滤掉最大数量记录的条件必须写在 Where 子句的末尾,HAVING 最后。

不要在where条件中使用左右两边都是%的like模糊查询,这样会导致数据库引擎放弃索引进行全表扫描。优化:尽量在字段后面使用模糊查询

尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,优化:可以用in代替or。

尽量不要在 where 子句中对字段进行表达式操作,这样也会造成全表扫描。

where条件里尽量不要进行null值的判断,null的判断也会造成全表扫描。给字段添加默认值,对默认值进行判断。

尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描

应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。将表达式.函数操作移动到等号右侧。

不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引

尽量不要使用where 1=1的条件,有时候,在开发过程中,为了方便拼装查询条件,我们会加上该条件,这样,会造成进行全表扫描。优化:如果用代码拼装sql,则由代码进行判断,没where加where,有where加and如果用mybatis,请用mybatis的where语法。

其他的优化

20.Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。

21.尽量使用Join 语句来替代子查询,因为子查询是嵌套查询,而嵌套查询会新创建一张临时表,而临时表的创建与销毁会占用一定的系统资源以及花费一定的时间,同时对于返回结果集比较大的子查询,其对查询性能的影响更大

22.对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会
很高,性能很差。

23.前提也是在sql基础优化完成后,有多表联合查询导致查询数据很慢,可以在代码上进行分割,如一条语句查多个表,可以拆分成两条sql语句或者多条sql语句,然后再代码上进行数据拼装。

24.业务层面优化是指在sql基础优化上没有问题之后,然后一次性查询的数据量很大,达到上亿的数据量,即使是分页也会很慢,所以要在业务层面进行优化,固定条件,缓存count值,避免每次查询全表扫描计算count值,每次更新都要对count值进行同步修改

Count优化

count(column) :是表示结果集中有多少个column字段不为空的记录。

count(*) :是表示整个结果集有多少条记录

count(1):InnoDB 引擎遍历整张表,但不取值。server 层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加。count(1) 执行得要比 count(主键 id) 快。因为从引擎返回 id 会涉及到解析数据行,以及拷贝字段值的操作。

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

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

相关文章

如何科学地利用MTTR优化软件交付流程?

谷歌提出的衡量 DevOps 质量的 DORA 指标让 MTTR&#xff08;平均恢复时间&#xff09; 名声大振。在本文中&#xff0c;你将了解到 MTTR 的作用、为什么它对行业研究很有用、你可能被它误导的原因以及如何避免 MTTR 产生的弊端。 MTTR 究竟是在测量什么&#xff1f; MTTR …

【服务器】springboot服务端接口公网远程调试 - 实现HTTP服务监听

文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址…

chatgpt赋能python:Python中如何删除:最全面的教程

Python中如何删除&#xff1a;最全面的教程 在Python编程中&#xff0c;许多情况下需要对数据进行操作&#xff0c;其中一种最基本的操作之一是删除。本文章将是一个关于Python中如何删除的最全面的教程。我们将会介绍Python中删除的概念、各种删除方法、删除前后的注意事项以…

同元自主可控半实物仿真从方案到实践

千寻万觅待花开 在日益激烈的市场竞争环境下&#xff0c;新产品的开发和面世遇到更高的要求和挑战&#xff0c;市场对其可靠性和稳定性的要求也日益提高。完全基于软件仿真的开发过程只实现了系统结构及原理、算法的验证&#xff0c;最终样机硬件系统并未进行仿真测试或者进行仿…

一寸照片的尺寸是多少?证件照尺寸如何修改?

一寸证件照是我们日常生活中非常常用的证件照。无论是办理身份证、驾驶证、护照还是其他证件&#xff0c;都需要提供一寸证件照。一寸证件照是指照片尺寸为2.5cm3.5cm的照片&#xff0c;通常要求符合一定的标准。但是大家在需要使用一寸证件照时&#xff0c;发现自己的证件照尺…

基于微信小程序制作一个记账小工具

你不理财,财不理你,制作一个记账小程序对自己的收入/支出明细进行管理,守护好自己的钱袋子。 一、小程序1.1 项目创建1.2 首页1.3 收支报表页1.4 记账提交页1.5 记账列表页

Transformer升级之路:一种全局长度外推的新思路

©PaperWeekly 原创 作者 | 苏剑林 单位 | 追一科技 研究方向 | NLP、神经网络 说到 Transformer 无法处理超长序列的原因&#xff0c;大家的第一反应通常都是 Self Attention 的二次复杂度。但事实上&#xff0c;即便忽略算力限制&#xff0c;常规的 Transformer 也无法处…

NetApp ONTAP Select 混合云存储解决方案

NetApp ONTAP Select 集敏捷性与经验证的数据管理功能于一体。 为什么选择 ONTAP Select 来实施混合云&#xff1f; -强大而敏捷的存储 既具备 ONTAP 软件的强大功能&#xff0c;也能够灵活地部署在远程办公室/后台位置以及数据中心外部的专用边缘环境中的商用硬件上。ONTAP …

python---逻辑运算符

and 并且 一假则假 or 或者 一真则真 not 逻辑取反 下面举例介绍上面代码的运行情况 运行结果如下: EG: 针对上述情况可以简化代码成如下: 短路操作 左侧为false右侧不在求值

如何使用 Megatron-LM 训练语言模型

在 PyTorch 中训练大语言模型不仅仅是写一个训练循环这么简单。我们通常需要将模型分布在多个设备上&#xff0c;并使用许多优化技术以实现稳定高效的训练。Hugging Face &#x1f917; Accelerate 的创建是为了支持跨 GPU 和 TPU 的分布式训练&#xff0c;并使其能够非常容易的…

WPS 借助 ML Kit 无缝翻译 43 种语言,每年净省 6,500 万美元

△ 动画说明: 在笔记本电脑屏幕中&#xff0c;汉字 "文" 将变为字母 "A"&#xff0c;代表文本的横线将逐一出现&#xff0c;就像有人在输入内容一样。 WPS 是一款办公套件软件&#xff0c;可让用户轻松查看和编辑其所有文档、演示文稿、电子表格等。作为一…

JetBrains的Go语言集成开发环境GoLand 2023版本在Win10系统的下载与安装配置教程

目录 前言一、GoLand 安装二、使用配置总结 前言 GoLand是一款专为Go语言开发人员设计的集成开发环境&#xff08;IDE&#xff09;。它提供了丰富的功能和工具&#xff0c;可以帮助开发人员更高效地编写、调试和部署Go应用程序。 GoLand的主要特点&#xff1a; ——代码编辑…

Learning C++ No.25【开散列封装unordered_set和unordered_map】

引言&#xff1a; 北京时间&#xff1a;2023/5/29/7:05&#xff0c;上星期更文一篇&#xff0c;且该篇博客在周三就写完了&#xff0c;所以充分体现&#xff0c;咱这个星期摆烂充分&#xff0c;哈哈哈&#xff01;现在的内心情感没有以前那么从容了&#xff0c;这次摆的时间是…

MySQL高级篇复盘笔记(二)【日志、主从复制、分库分表、读写分离】

❤ 作者主页&#xff1a;欢迎来到我的技术博客&#x1f60e; ❀ 个人介绍&#xff1a;大家好&#xff0c;本人热衷于Java后端开发&#xff0c;欢迎来交流学习哦&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 如果文章对您有帮助&#xff0c;记得关注、点赞、收藏、…

【Redis25】Redis进阶:分布式锁实现

Redis进阶&#xff1a;分布式锁实现 锁这个概念&#xff0c;不知道大家掌握的怎么样。我是先通过 Java &#xff0c;知道在编程语言中是如何使用锁的。一般 Java 的例子会是操作一个相同的文件&#xff0c;但其实我们知道&#xff0c;不管是文件&#xff0c;还是数据库中的一条…

Dapper存取Blob类型数据

&#x1f32e; Dapper存取Blob类型数据 前言&#xff1a; blob类型是数据库用于保存二进制文件的一种类型&#xff0c;可以将文件存储到数据库的表中。&#xff08;使用到的情况比较少&#xff0c;毕竟文件可以直接在服务器上保存并且访问为什么要放到数据库里。但如果你服务器…

1.MySQL安装与配置

1.MySQL安装与配置 &#x1f4e4;1 数据库介绍&#x1f4e4;&#x1f6aa;1.1关于MySQL主要要学啥&#x1f6aa; ✉️2 MySQL服务器安装✉️&#x1f4c4;2.1 Windows绿色安装&#x1f4c4;&#x1f4d1;2.2 Windows中重装MySQL&#x1f4d1; &#x1f4e8;3 Mac中常见的安装问…

多云环境中的微服务应用安全挑战

随着越来越多的组织将云策略扩展到私有云、公共云、本地数据中心和边缘站点&#xff0c;将多云作为数字转型倡议的一部分&#xff0c;新的安全挑战不断涌现&#xff0c;必须在安全倡议的每个阶段加以考虑。 在云中操作具有多个优势&#xff0c;任何组织&#xff0c;无论是公共…

在线答题小程序制作,这些坑你一定要避免

在线答题小程序制作&#xff0c;你需要知道以下几个关键点&#xff0c;才能避免一些常见的坑。这里&#xff0c;我会为你详细介绍如何制作一个高质量的在线答题小程序。 关键点一&#xff1a;确定目标用户群体 在制作在线答题小程序之前&#xff0c;你需要确定你的目标用户群…

行云创新受邀参加阿里云开发者技术沙龙,分享云原生技术实践案例

云原生IDE&#xff0c;定义开发新常态 2023年5月28日&#xff0c;由阿里举办的云原生技术实践营-阿里云开发者技术沙龙在深圳市南山区成功举办。本次沙龙活动主要围绕云原生话题开展实践案例经验分享&#xff0c;行云创新CEO马洪喜作为受邀嘉宾之一&#xff0c;参加了本次活动…