52条SQL语句性能优化策略,推荐收藏!

 2024-02-15 02:05:19  阅读 0

点击上面的“Yudao Code”,选择“”

她是前浪还是后浪有关系吗?

能浪的就是好浪!

文章每天8点55分更新,每天都有几亿根头发掉……

源码精品专栏

来源://p/.html

为了优化查询,应该尽量避免全表扫描,首先考虑对where和order by涉及到的列创建索引

应尽量避免对where子句中的字段进行空值判断。 NULL是创建表时的默认值,但大多数时候应该使用NOT NULL,或者使用特殊的值,如0、-1作为默认值。

您应该尽量避免在 where 子句中使用 != 或运算符。 MySQL 仅对以下运算符使用索引:=、IN,有时还有 LIKE。

尽量避免在where子句中使用or来连接条件,否则引擎会放弃使用索引而执行全表扫描。 您可以使用 UNION 合并查询: id from t where num=10 union all id from t where num=20

in和not in也应该谨慎使用,否则会导致全表扫描。 对于连续值,如果可以使用就不要使用in:id from t where num 1 and 3

下面的查询也会导致全表扫描: id from t where name like '%abc%' 或者 id from t where name like '%abc' 为了提高效率,可以考虑全文检索。索引只是用于 t 中的 id,其中名称如“abc%”

如果where子句中使用了参数,也会导致全表扫描。

应尽可能避免对where子句中的字段进行表达式操作,并尽可能避免对where子句中的字段进行函数操作。

很多时候,替换 in: num from a where num in( num from b) 是一个不错的选择。 替换为以下语句: num from a where ( 1 from b where num=a.num)

10

虽然索引可以提高相应的效率,但同时也降低了效率,因为索引可能时不时地被重建,所以如何构建索引需要仔细考虑,根据具体情况而定。 一个表上的索引最好不要超过6个。 如果太多,就应该考虑是否有必要对一些不常用的列建立索引。

11

应尽可能避免更新索引数据列,因为索引数据列的顺序就是表记录的物理存储顺序。 一旦列值发生变化,整个表记录的顺序就会调整,这会消耗相当大的资源。 如果应用系统需要频繁更新索引数据列,那么就需要考虑是否应该将索引建为索引。

12

尝试使用数字字段。 如果字段只包含数字信息,尽量不要将其设计为字符字段。 这会降低查询和连接的性能,并增加存储开销。

13

尽量用/代替char/nchar,因为首先变长字段存储空间小,可以节省存储空间。 其次,对于查询来说,在相对较小的领域内搜索效率明显更高。

14

最好不要使用“”返回全部:从 t 中,将“*”替换为特定字段列表,并且不返回任何未使用的字段。

15

尽量避免向客户端返回大量数据。 如果数据量太大,就应该考虑相应的要求是否合理。

16

使用表别名(Alias):在SQL语句中连接多个表时,请使用表别名并为每个别名添加前缀。 通过这种方式,您可以减少解析时间并减少由歧义引起的错误。 语法错误。

17 号

使用“临时表”暂存中间结果

简化SQL语句的一个重要方法是使用临时表来临时存储中间结果。 然而,临时表的好处远不止这些。 如果将临时结果临时存储在临时表中,则后续查询将是正确的。 这样可以避免程序中的多次扫描。 主表还大大减少了程序执行过程中的“共享锁”阻塞和“更新锁”,减少阻塞,提高并发性能。

18

应该添加一些SQL查询语句。 读和写会互相阻塞。 为了提高并发性能,可以增加一些查询,使得读的时候也允许写。 但缺点是可能会读取到未提交的脏数据。 使用原则有3条。 用于“插入、删除、修改”的查询结果无法添加! 所查询的表是经常发生分页的表,请谨慎使用! 临时表还可以用来保存“数据预示”,并提供与撤消表空间类似的功能。 如果可以使用临时表来提高并发性能,请不要使用它们。

19

常见的简化规则如下: 不要超过5个表连接(JOIN),并考虑使用临时表或表变量来存储中间结果。 少用子查询,并且不要嵌套视图太深。 一般嵌套视图不超过2个为宜。

20

预先计算出需要查询的结果放入表中,然后再次查询。 这是SQL7.0之前最重要的方法。 例如医院住院费用计算。

21

OR子句可以分解为多个查询,多个查询可以通过UNION连接起来。 它们的速度只与是否使用索引有关。 如果查询需要使用联合索引,那么使用UNION all效率更高。 多个OR语句不使用索引,以UNION的形式重写并尝试匹配索引。 一个关键问题是是否使用索引。

22

IN后的值列表中,将最常出现的值放在前面,最不常见的值放在最后,以减少判断次数。

23

尽量将数据处理工作放在服务器上,以减少网络开销,例如使用存储过程。 存储过程是经过编译、优化、组织成执行计划并存储在数据库中的 SQL 语句。 它们是控制流语言的集合,当然速度很快。 重复执行的动态SQL可以使用临时存储过程(临时表)。

24

当服务器内存足够的情况下,配置线程数=最大连接数+5,这样可以最大化效率; 否则,使用配置的线程数=“,不要使用”>”。

28

索引使用规范:索引的创建要结合应用来考虑。 建议大型OLTP表的索引不要超过6个; 尽可能使用索引字段作为查询条件,尤其是聚集索引。 如果需要,可以使用index强制指定索引。 ;查询大表时避免表扫描,必要时考虑创建新索引; 使用索引字段作为条件时,如果索引是联合索引,那么必须使用索引中的第一个字段作为条件,以保证系统使用该索引,否则不会使用该索引; 注意索引的维护,定期重建索引,重新编译存储过程。

29

下面的SQL条件语句中的列虽然索引正确,但是执行速度很慢:

SELECT * FROM record WHERE substrINg(card_no,1,4)=’5378’ (13秒)

SELECT * FROM record WHERE amount/301000 (11秒)

SELECT * FROM record WHERE convert(char(10),date,112)=’19991201’ (10秒)

分析:

SQL运行时,WHERE子句中对列的任何操作的结果都是逐列计算的,因此必须进行表搜索,而不使用列上的索引; 如果这些结果在查询编译时可用,那么它可以由 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语句,我绝对不会用循环来实现!

(例如:要列出上个月的每一天,我会使用 by 递归查询,并且永远不会使用从上个月的第一天到最后一天的循环)

32

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

解析器按照从右到左的顺序处理 FROM 子句中的表名。 FROM 子句中最后写入的表(基表表)将首先被处理。 当FROM子句Next中包含多个表时,必须选择记录数最少的表作为基表。 如果查询连接的表超过3个,则需要选择一个交叉表(表)作为基表。 交叉表是指被其他表引用的表。

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语句是大写的,因为sql语句总是先解析,在执行之前将小写字母转换为大写字母。

35

别名的使用,别名是大型数据库的一种应用技术,即在查询中为表名和列名加上一个字母的别名,查询速度比建连接表快1.5倍。

36

为了避免死锁,请始终在存储过程和触发器中以相同的顺序访问同一个表; 事务应尽可能缩短,并且事务所涉及的数据量应尽可能减少; 从不等待用户输入。

37

除非必要,否则避免使用临时表。 相反,使用表变量; 大多数时候(99%),表变量驻留在内存中,因此比临时表更快。 表驻留在数据库中,因此对临时表的操作需要跨数据库通信,这自然很慢。

38

最好不要使用触发器。 触发触发器并执行触发事件本身就是一个消耗资源的过程; 如果可以使用约束来实现,尽量不要使用触发器; 不要对不同的触发事件使用相同的触发事件(、)。 触发器; 不要在触发器中使用事务代码。

39

索引创建规则:

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

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

经常与其他表连接的表应该在连接字段上创建索引;

对于Where子句中频繁出现的字段,尤其是大表中的字段,应该建立索引;

索引应建立在高度选择性的领域;

索引应该建立在小字段上。 不要在大文本字段甚至非常长的字段上建立索引;

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

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

复合索引的几个字段是否经常以AND方式同时出现在Where子句中? 单字段查询很少或没有吗? 如果是,则可以建立综合指数; 否则,可以考虑单字段索引;

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

如果复合索引包含的字段超过3个,请仔细考虑必要性,考虑减少复合字段的数量;

如果这些字段同时存在单字段索引和复合索引,一般可以删除复合索引;

对于数据操作频繁的表,不要创建过多的索引;

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

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

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

40

mysql查询优化总结:使用慢查询日志来查找慢查询,使用执行计划来确定查询是否正常运行,并始终测试您的查询以查看它们是否以最佳状态运行。性能总是会随着时间而变化,避免使用 count( *) 在整个表上,可能会锁定整个表,使查询一致,以便后续类似的查询可以使用查询缓存

,在适当的时候使用GROUP BY代替,在WHERE、GROUP BY和ORDER BY子句中使用索引列,保持索引简单,不要在多个索引中包含同一列,有时MySQL会使用错误的索引,这种情况使用USE INDEX,检查使用=的问题,对于少于5条记录的索引字段,UNION不使用OR时使用LIMIT。

为了避免在更新之前使用ON KEY或者,不要使用来实现,不要使用MAX,使用索引字段和ORDER BY子句,LIMIT M, N在某些情况下实际上会减慢查询速度,请谨慎使用,在使用UNION在 WHERE 子句中而不是在子查询中。 重新启动 MySQL 后,请记住预热数据库,以确保数据在内存中并且查询速度很快。 考虑持久连接而不是多个连接以减少开销。 基准查询包括使用服务器上的负载。 有时,一个简单的查询可能会影响其他查询。 当服务器上的负载增加时,使用 SHOW 查看缓慢且有问题的查询。 对开发环境中生成的镜像数据进行全部测试。 可疑的询问。

41

MySQL备份流程:

从辅助复制服务器获取备份。 进行备份时停止复制,以避免数据依赖性和外键约束不一致。 完全停止 MySQL 并从数据库文件中进行备份。

如果您使用 MySQL dump 进行备份,请同时备份二进制日志文件 – 以确保复制不会中断。 不要相信 LVM 快照,它们可能会造成数据不一致,从而在将来给您带来麻烦。 为了使单表恢复更容易,请以表为单位导出数据 - 如果数据与其他表隔离。

使用时请加上--opt。 备份前检查并优化表。 为了加快导入速度,导入期间暂时禁用外键约束。

为了加快导入速度,导入期间暂时禁用唯一性检查。 每次备份后计算数据库、表和索引的大小,以更好地监控数据大小的增长。

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

42

查询缓存不会自动处理空格。 因此,在编写SQL语句时,应尽量减少空格的使用,尤其是SQL开头和结尾的空格(因为查询缓存不会自动拦截开头和结尾的空格)。

43

以mid为标准分表查询方便吗? 一般业务需求中,基本都会用到查询依据。 一般情况下应该是通过做hash取模来分表的。 如果分表的话,mysql的功能就是干这个的,而且对代码是透明的;

从代码层面实现似乎不太合理。

44

我们应该为数据库中的每个表设置一个ID作为主键,最好是INT类型(推荐),并设置自增标志。

45

在所有存储过程和触发器的开头设置 SET ON,并在结尾设置 SET OFF。

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

46

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

47

查询用于跟踪观看效果

使用关键字可以让您了解 MySQL 如何处理您的 SQL 语句。 这可以帮助您分析查询语句或表结构的性能瓶颈。 查询结果还会告诉你你的索引主键是如何使用的,你的数据表是如何搜索和排序的......等等。

48

当您只需要一行数据时,请使用 LIMIT 1

有时当你查询一张表时,你已经知道结果只会是一个结果,但是因为你可能需要获取游标,或者你可能想检查返回的记录数。 在这种情况下,添加 LIMIT 1 可以提高性能。 这样,MySQL数据库引擎在找到一条数据后就会停止搜索,而不是继续搜索下一条与该记录匹配的数据。

49

为表选择合适的存储引擎:

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

:并发条件下要求的事务处理、数据一致性。 除了插入和查询之外,还包括很多更新和删除。 (有效减少删除和更新引起的锁定)。 对于支持事务的表,影响速度的主要原因是默认设置开启,程序没有显式调用BEGIN启动事务,导致每次插入都自动提交,严重影响速度。 您可以在执行 SQL 之前调用 begin。 多个SQL形成一个事务(即使是开启的),这样会大大提高性能。

50

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

原则:越小越好,简单越好,所有字段必须有默认值,并尽量避免null。

例如:在设计数​​据库表时,尽可能使用较小的整数类型,以占用较少的磁盘空间(比int更合适)。

例如时间字段:and占用8个字节,而while占用4个字节,只使用了一半,表示的范围是1970-2037,适合更新时间

MySQL可以很好地支持大量数据的访问,但一般来说,数据库中的表越小,对其执行查询的速度就越快。

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

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

即使使用这种类型也是多余的,因为 CHAR(6) 可以很好地完成这项工作。 同样,如果可以的话,

我们应该使用 BIGIN 而不是定义整数字段。

应尽量将该字段设置为NOT NULL,这样数据库以后执行查询时就不需要比较NULL值了。

对于一些文本字段,例如“省份”或“性别”,我们可以将它们定义为ENUM类型。 因为在MySQL中,ENUM类型被视为数值数据,

数字数据的处理速度比文本数据快得多。 这样,我们就可以提高数据库的性能。

51

字符串数据类型:char、文本选择区别

52

对列的任何操作都会导致表扫描,其中包括数据库函数、计算表达式等,查询时应尽量将操作移至等号右侧。

欢迎加入我的知识星球讨论架构、交流源码。 长按下方二维码即可加入:

sqlserver取前几位_sql server 取前10条_sql取前10条

知识星球更新后的源码分析如下:

《土豆入门2..》系列

提供了近3W行代码的示例,以及超过4W行代码的电商微服务项目。

标签: 索引 字段 查询

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码