Mysql性能优化

本文探讨了MySQL数据库的性能优化,包括设计优化和查询优化。设计优化建议选择合适的数据类型,避免使用NULL,并优化字段类型。查询优化中,应避免全表扫描,如使用select*,前缀模糊查询,负向查询,函数运算以及深度分页。建议使用覆盖索引,避免数学运算和函数操作,并采用更有效的分页方式。
摘要由CSDN通过智能技术生成

—————————— Yesterday is history, tomorrow is a mystery, but today is a gift. That is why it’s called the present. ——————————


性能优化可分为两部分:设计优化和查询优化

1. 设计优化

1.1 字段类型

1、数据类型越小越好,数据越小需要的存储空间就越小,每个页能够存储的信息就越多。例如 tinyint 占据一个字节,可存储 0~255 范围内的数值(无符号)。smallint 占据两个字节,可存储 0~65535 范围内的数值(无符号),需要根据具体的场景来选择最合适的类型。
2、简单的数据类型操作代价更低
3、尽量避免使用null,可以限定列not null。因为null存储需要额外的空间,可以考虑使用0来代替null。

2. 查询优化

2.1 不要使用 select * 进行查询

这个提到的很多,可以分为两种情况,一种是 select * from students where id = 2,id是主键,也就是使用聚簇索引进行查询。这种情况下是可以一次查询到所有的信息,此时使用 select *的主要影响是会增加内存和网络消耗。
另外一种情况是 select * from students where name = 'zhou',name是普通索引,也就是使用非聚簇索引进行查询。这种情况下需要进行回表操作,根据聚簇索引查找其他信息。如果只需要name和age两个字段,可以创建name_age联合索引,使用 select name, age from students where name = 'zhou' 进行查询,这样就不用再进行回表,即覆盖索引。

2.2 使用like时避免前缀模糊查询

一般不建议使用like,如果使用 select from students where name like '%xxx%' 这样的语句是不能走索引的,但是使用 like 'zhou%' 可以走索引查询。
在这里插入图片描述students 表中共有8条记录,其中 name 有普通索引,使用 select * from students where name like 'zhou%' 是可以走索引的。在这里插入图片描述

2.4 尽量避免负向查询

尽量不要使用 not null、!=、<>、not in、not like 这些查询词,负向查询不会走索引,但不是绝对的。创建测试表 testTable1,表中有2000条数据,其中 num=0 700条,num=1 300条,num=2 1000条,已创建 num_sta 联合索引。
在这里插入图片描述
使用 select * from testTable1 where num != 2进行查询,会进行全表扫描。
在这里插入图片描述
可以考虑使用 select * from testTable1 where num = 0 UNION ALL select * from testTable1 where num = 1 进行查询
在这里插入图片描述
使用 select num from testTable1 where num != 2 进行查询,即覆盖索引,是可以走索引的
在这里插入图片描述

2.5 禁止在索引字段上做数学运算或函数运算

对索引字段上做数学运算或函数运算可能会破坏索引的有序性,所以优化器会放弃走索引。只要进行数学运算和函数运算就不会走索引,就算没有破坏索引有序性。

同样根据上表进行举例,select * from testTable1 where num = 0 会走索引,但是 select * from testTable1 where num + 1 = 1 不会索引,尽管数学运算并没有破坏索引有序性。

注意,隐式类型转换同样属于函数运算,这里需要了解 mysql 进行隐式类型转换的规则:
The following rules describe how conversion occurs for comparison operations:
1. If one or both arguments are NULL, the result of the comparison is NULL, except for the NULL-safe <=> equality comparison operator. For NULL <=> NULL, the result is true. No conversion is needed.
2. If both arguments in a comparison operation are strings, they are compared as strings.
3. If both arguments are integers, they are compared as integers.
4. Hexadecimal values are treated as binary strings if not compared to a number.
5. If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. This is not done for the arguments to IN(). To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type.
A single-row subquery from a table or tables is not considered a constant. For example, if a subquery returns an integer to be compared to a DATETIME value, the comparison is done as two integers. The integer is not converted to a temporal value. To compare the operands as DATETIME values, use CAST() to explicitly convert the subquery value to DATETIME.
6. If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value.
In all other cases, the arguments are compared as floating-point (double-precision) numbers. For example, a comparison of string and numeric operands takes place as a comparison of floating-point numbers.

测试表 testTable1 中的 sta 字段类型是 char,如果将其和数值进行比较则不会走索引,例如:select * from testTable1 where sta = 1,这个sql相当于 select * from testTable1 where cast(sta as float) = 1,同样是对字段进行函数运算。

Mysql官方文档

2.6 不要进行深度分页查询

分页查询是经常使用的,但是不要进行深度分页查询,例如 SELECT * FROM u_server_order LIMIT 10 OFFSET 10000,会先筛选100010数据,然后进行回表,再返回最后的10条数据。 有以下两个个办法可以进行优化:
1、先查询ID,进行截取后再查询需要的字段。
2、添加上次查询的结果作为限制条件,例如 SELECT * FROM testTable WHERE id > XXX LIMIT 10

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值