当前位置: 代码网 > it编程>数据库>Mysql > MySQL 数据库中 52 条 SQL 语句性能优化方法,干货必收藏!

MySQL 数据库中 52 条 SQL 语句性能优化方法,干货必收藏!

2024年08月02日 Mysql 我要评论
在适当的情形下使用GROUP BY而不是DISTINCT,在WHERE, GROUP BY和ORDER BY子句中使用有索引的列,保持索引简单,不在多个索引中包含同一个列,有时候MySQL会使用错误的索引,对于这种情况使用USE INDEX,检查使用SQL_MODE=STRICT的问题,对于记录数小于5的索引字段,在UNION的时候使用LIMIT不是是用OR。大多数时候(99%),表变量驻扎在内存中,因此速度比临时表更快,临时表驻扎在TempDb数据库中,因此临时表上的操作需要跨数据库通信,速度自然慢。

select * from record where amount/30< 1000 (11秒)

select * from record where convert(char(10),date,112)=‘19991201’ (10秒)

分析:

where子句中对列的任何操作结果都是在sql运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被sql优化器优化,使用索引,避免表搜索,因此将sql重写成下面这样:

select * from record where card_no like ‘5378%’ (< 1秒)

select * from record where amount< 1000*30 (< 1秒)

select * from record where date= ‘1999/12/01’ (< 1秒)

30,当有一批处理的插入或更新时,用批量插入或批量更新,绝不会一条条记录的去更新!

31,在所有的存储过程中,能够用sql语句的,我绝不会用循环去实现!

(例如:列出上个月的每一天,我会用connect by去递归查询一下,绝不会去用循环从上个月第一天到最后一天)

32,选择最有效率的表名顺序(只在基于规则的优化器中有效):

oracle 的解析器按照从右到左的顺序处理from子句中的表名,from子句中写在最后的表(基础表 driving table)将被最先处理,在from子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(interp table)作为基础表, 交叉表是指那个被其他表所引用的表.

33,提高group by语句的效率, 可以通过将不需要的记录在group by 之前过滤掉.下面两个查询返回相同结果,但第二个明显就快了许多.

低效:

select job , avg(sal)

from emp

group by job

having job =‘president’

or job =‘manager’

高效:

select job , avg(sal)

from emp

where job =‘president’

or job =‘manager’

group by job

34,sql语句用大写,因为oracle 总是先解析sql语句,把小写的字母转换成大写的再执行。

35,别名的使用,别名是大型数据库的应用技巧,就是表名、列名在查询中以一个字母为别名,查询速度要比建连接表快1.5倍。

36,避免死锁,在你的存储过程和触发器中访问同一个表时总是以相同的顺序;事务应经可能地缩短,在一个事务中应尽可能减少涉及到的数据量;永远不要在事务中等待用户输入。

37,避免使用临时表,除非却有需要,否则应尽量避免使用临时表,相反,可以使用表变量代替;大多数时候(99%),表变量驻扎在内存中,因此速度比临时表更快,临时表驻扎在tempdb数据库中,因此临时表上的操作需要跨数据库通信,速度自然慢。

38,最好不要使用触发器,触发一个触发器,执行一个触发器事件本身就是一个耗费资源的过程;如果能够使用约束实现的,尽量不要使用触发器;不要为不同的触发事件(insert,update和delete)使用相同的触发器;不要在触发器中使用事务型代码。

39,索引创建规则:

表的主键、外键必须有索引;

数据量超过300的表应该有索引;

经常与其他表进行连接的表,在连接字段上应该建立索引;

经常出现在where子句中的字段,特别是大表的字段,应该建立索引;

索引应该建在选择性高的字段上;

索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;

复合索引的建立需要进行仔细分析,尽量考虑用单字段索引代替;

正确选择复合索引中的主列字段,一般是选择性较好的字段;

复合索引的几个字段是否经常同时以and方式出现在where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引;

如果复合索引中包含的字段经常单独出现在where子句中,则分解为多个单字段索引;

如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;

如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;

频繁进行数据操作的表,不要建立太多的索引;

删除无用的索引,避免对执行计划造成负面影响;

表上建立的每个索引都会增加存储开销,索引对于插入、删除、更新操作也会增加处理上的开销。另外,过多的复合索引,在有单字段索引的情况下,一般都是没有存在价值的;相反,还会降低数据增加删除时的性能,特别是对频繁更新的表来说,负面影响更大。

尽量不要对数据库中某个含有大量重复的值的字段建立索引。

40,mysql查询优化总结:使用慢查询日志去发现慢查询,使用执行计划去判断查询是否正常运行,总是去测试你的查询看看是否他们运行在最佳状态下。久而久之性能总会变化,避免在整个表上使用count(*),它可能锁住整张表,使查询保持一致以便后续相似的查询可以使用查询缓存

,在适当的情形下使用group by而不是distinct,在where, group by和order by子句中使用有索引的列,保持索引简单,不在多个索引中包含同一个列,有时候mysql会使用错误的索引,对于这种情况使用use index,检查使用sql_mode=strict的问题,对于记录数小于5的索引字段,在union的时候使用limit不是是用or。

为了 避免在更新前select,使用insert on duplicate key或者insert ignore ,不要用update去实现,不要使用 max,使用索引字段和order by子句,limit m,n实际上可以减缓查询在某些情况下,有节制地使用,在where子句中使用union代替子查询,在重新启动的mysql,记得来温暖你的数据库,以确保您的数据在内存和查询速度快,考虑持久连接,而不是多个连接,以减少开销,基准查询,包括使用服务器上的负载,有时一个简单的查询可以影响其他查询,当负载增加您的服务器上,使用show processlist查看慢的和有问题的查询,在开发环境中产生的镜像数据中 测试的所有可疑的查询。

41,mysql 备份过程:

从二级复制服务器上进行备份。在进行备份期间停止复制,以避免在数据依赖和外键约束上出现不一致。彻底停止mysql,从数据库文件进行备份。

如果使用 mysql dump进行备份,请同时备份二进制日志文件 – 确保复制没有中断。不要信任lvm 快照,这很可能产生数据不一致,将来会给你带来麻烦。为了更容易进行单表恢复,以表为单位导出数据 – 如果数据是与其他表隔离的。

当使用mysqldump时请使用 –opt。在备份之前检查和优化表。为了更快的进行导入,在导入时临时禁用外键约束。

为了更快的进行导入,在导入时临时禁用唯一性检测。在每一次备份后计算数据库,表以及索引的尺寸,以便更够监控数据尺寸的增长。

通过自动调度脚本监控复制实例的错误和延迟。定期执行备份。

42,查询缓冲并不自动处理空格,因此,在写sql语句时,应尽量减少空格的使用,尤其是在sql首和尾的空格(因为,查询缓冲并不自动截取首尾空格)。

43,member用mid做標準進行分表方便查询么?一般的业务需求中基本上都是以username为查询依据,正常应当是username做hash取模来分表吧。分表的话 mysql 的partition功能就是干这个的,对代码是透明的;

在代码层面去实现貌似是不合理的。

44,我们应该为数据库里的每张表都设置一个id做为其主键,而且最好的是一个int型的(推荐使用unsigned),并设置上自动增加的auto_increment标志。

45,在所有的存储过程和触发器的开始处设置 set nocount on ,在结束时设置 set nocount off 。

无需在执行存储过程和触发器的每个语句后向客户端发送 done_in_proc 消息。

46,mysql查询可以启用高速查询缓存。这是提高数据库性能的有效mysql优化方法之一。当同一个查询被执行多次时,从缓存中提取数据和直接从数据库中返回数据快很多。

47,explain select 查询用来跟踪查看效果

使用 explain 关键字可以让你知道mysql是如何处理你的sql语句的。这可以帮你分析你的查询语句或是表结构的性能瓶颈。explain 的查询结果还会告诉你你的索引主键被如何利用的,你的数据表是如何被搜索和排序的……等等,等等。

48,当只要一行数据时使用 limit 1

当你查询表的有些时候,你已经知道结果只会有一条结果,但因为你可能需要去fetch游标,或是你也许会去检查返回的记录数。在这种情况下,加上 limit 1 可以增加性能。这样一样,mysql数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。

49,选择表合适存储引擎:

myisam: 应用时以读和插入操作为主,只有少量的更新和删除,并且对事务的完整性,并发性要求不是很高的。

innodb:事务处理,以及并发条件下要求数据的一致性。除了插入和查询外,包括很多的更新和删除。(innodb有效地降低删除和更新导致的锁定)。对于支持事务的innodb类型的表来说,影响速度的主要原因是autocommit默认设置是打开的,而且程序没有显式调用begin 开始事务,导致每插入一条都自动提交,严重影响了速度。可以在执行sql前调用begin,多条sql形成一个事物(即使autocommit打开也可以),将大大提高性能。

50,优化表的数据类型,选择合适的数据类型:

原则:更小通常更好,简单就好,所有字段都得有默认值,尽量避免null。

例如:数据库表设计时候更小的占磁盘空间尽可能使用更小的整数类型.(mediumint就比int更合适)

比如时间字段:datetime和timestamp, datetime占用8个字节,而timestamp占用4个字节,只用了一半,而timestamp表示的范围是1970—2037适合做更新时间

mysql可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。

因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。例如,

在定义邮政编码这个字段时,如果将其设置为char(255),显然给数据库增加了不必要的空间,

甚至使用varchar这种类型也是多余的,因为char(6)就可以很好的完成任务了。同样的,如果可以的话,

我们应该使用mediumint而不是bigin来定义整型字段。

应该尽量把字段设置为not null,这样在将来执行查询的时候,数据库不用去比较null值。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、oppo等大厂,18年进入阿里一直到现在。

深知大多数java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注java获取)

img

感受:

其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

也祝愿各位同学,都能找到自己心动的offer。

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

拿到字节跳动offer后,简历被阿里捞了起来,二面迎来了p9"盘问"

《一线大厂java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》
的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

也祝愿各位同学,都能找到自己心动的offer。

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

[外链图片转存中…(img-sulxluwh-1712176577096)]

《一线大厂java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》

(0)

相关文章:

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

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com