首页数据库mysql数据库优化(mysql 优化包括哪些内容)

mysql数据库优化(mysql 优化包括哪些内容)

编程之家2023-10-21107次浏览

大家好,感谢邀请,今天来为大家分享一下mysql数据库优化的问题,以及和mysql 优化包括哪些内容的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!

mysql数据库优化(mysql 优化包括哪些内容)

mysql 优化包括哪些内容

mysql的优化大的有两方面:

1、配置优化

配置的优化其实包含两个方面的:操作系统内核的优化和mysql配置文件的优化

1)系统内核的优化对专用的mysql服务器来说,无非是内存实用、连接数、超时处理、TCP处理等方面的优化,根据自己的硬件配置来进行优化,这里不多讲;

2)mysql配置的优化,一般来说包含:IO处理的常用参数、最大连接数设置、缓存使用参数的设置、慢日志的参数的设置、innodb相关参数的设置等,如果有主从关系在设置主从同步的相关参数即可,网上的相关配置文件很多,大同小异,常用的设置大多修改这些差不多就够用了。

2、sql语句的优化

mysql数据库优化(mysql 优化包括哪些内容)

1、尽量稍作计算

Mysql的作用是用来存取数据的,不是做计算的,做计算的话可以用其他方法去实现,mysql做计算是很耗资源的。

2.尽量少 join

MySQL的优势在于简单,但这在某些方面其实也是其劣势。MySQL优化器效率高,但是由于其统计信息的量有限,优化器工作过程出现偏差的可能性也就更多。对于复杂的多表 Join,一方面由于其优化器受限,再者在 Join这方面所下的功夫还不够,所以性能表现离 Oracle等关系型数据库前辈还是有一定距离。但如果是简单的单表查询,这一差距就会极小甚至在有些场景下要优于这些数据库前辈。

mysql数据库优化(mysql 优化包括哪些内容)

3.尽量少排序

排序操作会消耗较多的 CPU资源,所以减少排序可以在缓存命中率高等 IO能力足够的场景下会较大影响 SQL的响应时间。

对于MySQL来说,减少排序有多种办法,比如:

通过利用索引来排序的方式进行优化

减少参与排序的记录条数

非必要不对数据进行排序

4.尽量避免 select*

在数据量少并且访问量不大的情况下,select*没有什么影响,但是量级达到一定级别的时候,在执行效率和IO资源的使用上,还是有很大关系的,用什么字段取什么字段,减少不必要的资源浪费。

之前遇到过因为一个字段存储的数据比较大,并发高的情况下把网络带宽跑满的情况,造成网站打不开或是打开速度极慢的情况。

5.尽量用 join代替子查询

虽然 Join性能并不佳,但是和 MySQL的子查询比起来还是有非常大的性能优势。MySQL的子查询执行计划一直存在较大的问题,虽然这个问题已经存在多年,但是到目前已经发布的所有稳定版本中都普遍存在,一直没有太大改善。虽然官方也在很早就承认这一问题,并且承诺尽快解决,但是至少到目前为止我们还没有看到哪一个版本较好的解决了这一问题。

6.尽量少 or

当 where子句中存在多个条件以“或”并存的时候,MySQL的优化器并没有很好的解决其执行计划优化问题,再加上 MySQL特有的 SQL与 Storage分层架构方式,造成了其性能比较低下,很多时候使用 union all或者是union(必要的时候)的方式来代替“or”会得到更好的效果。

7.尽量用 union all代替 union

union和 union all的差异主要是前者需要将两个(或者多个)结果集合并后再进行唯一性过滤操作,这就会涉及到排序,增加大量的 CPU运算,加大资源消耗及延迟。所以当我们可以确认不可能出现重复结果集或者不在乎重复结果集的时候,尽量使用 union all而不是 union。

8.尽量早过滤

这一优化策略其实最常见于索引的优化设计中(将过滤性更好的字段放得更靠前)。

在 SQL编写中同样可以使用这一原则来优化一些 Join的 SQL。比如我们在多个表进行分页数据查询的时候,我们最好是能够在一个表上先过滤好数据分好页,然后再用分好页的结果集与另外的表 Join,这样可以尽可能多的减少不必要的 IO操作,大大节省 IO操作所消耗的时间。

9.避免类型转换

这里所说的“类型转换”是指 where子句中出现 column字段的类型和传入的参数类型不一致的时候发生的类型转换:

A:人为在column_name上通过转换函数进行转换

直接导致 MySQL(实际上其他数据库也会有同样的问题)无法使用索引,如果非要转换,应该在传入的参数上进行转换

B:由数据库自己进行转换

如果我们传入的数据类型和字段类型不一致,同时我们又没有做任何类型转换处理,MySQL可能会自己对我们的数据进行类型转换操作,也可能不进行处理而交由存储引擎去处理,这样一来,就会出现索引无法使用的情况而造成执行计划问题。

以上两种情况在开发者因为某种原因经常会有,本来可以用到索引的结果类型不对没有用到索引,或是因为类型不对又有越界的情况发生造成无法使用索引的情况,结果造成很严重的事故。

10.优先优化高并发的 SQL,而不是执行频率低某些“大”SQL

对于破坏性来说,高并发的 SQL总是会比低频率的来得大,因为高并发的 SQL一旦出现问题,甚至不会给我们任何喘息的机会就会将系统压跨。而对于一些虽然需要消耗大量 IO而且响应很慢的 SQL,由于频率低,即使遇到,最多就是让整个系统响应慢一点,但至少可能撑一会儿,让我们有缓冲的机会。

11.从全局出发优化,而不是片面调整

SQL优化不能是单独针对某一个进行,而应充分考虑系统中所有的 SQL,尤其是在通过调整索引优化 SQL的执行计划的时候,千万不能顾此失彼,因小失大。

12.尽可能对每一条运行在数据库中的SQL进行 explain

优化 SQL,需要做到心中有数,知道SQL的执行计划才能判断是否有优化余地,才能判断是否存在执行计划问题。在对数据库中运行的 SQL进行了一段时间的优化之后,很明显的问题 SQL可能已经很少了,大多都需要去发掘,这时候就需要进行大量的 explain操作收集执行计划,并判断是否需要进行优化。

mysql数据库优化的几种方法

其次,在建有索引的字段上尽量不要使用函数进行操作。

例如,在一个DATE类型的字段上使用YEAE()函数时,将会使索引不能发挥应有的作用。所以,下面的两个查询虽然返回的结果一样,但后者要比前者快得多。

第三,在搜索字符型字段时,我们有时会使用LIKE关键字和通配符,这种做法虽然简单,但却也是以牺牲系统性能为代价的。

例如下面的查询将会比较表中的每一条记录。

SELECT* FROM books WHERE name like"MySQL%"

但是如果换用下面的查询,返回的结果一样,但速度就要快上很多:

SELECT* FROM books WHERE name>="MySQL"and name<"MySQM"

最后,应该注意避免在查询中让MySQL进行自动类型转换,因为转换过程也会使索引变得不起作用。

mysql数据库优化的几种方法

标签:rod订单特殊code完成字符型数值子查询应用

mysql数据库怎么优化,有几方面的优化

在开始演示之前,我们先介绍下两个概念。

概念一,数据的可选择性基数,也就是常说的cardinality值。

查询优化器在生成各种执行计划之前,得先从统计信息中取得相关数据,这样才能估算每步操作所涉及到的记录数,而这个相关数据就是cardinality。简单来说,就是每个值在每个字段中的唯一值分布状态。

比如表t1有100行记录,其中一列为f1。f1中唯一值的个数可以是100个,也可以是1个,当然也可以是1到100之间的任何一个数字。这里唯一值越的多少,就是这个列的可选择基数。

那看到这里我们就明白了,为什么要在基数高的字段上建立索引,而基数低的的字段建立索引反而没有全表扫描来的快。当然这个只是一方面,至于更深入的探讨就不在我这篇探讨的范围了。

概念二,关于HINT的使用。

这里我来说下HINT是什么,在什么时候用。

HINT简单来说就是在某些特定的场景下人工协助MySQL优化器的工作,使她生成最优的执行计划。一般来说,优化器的执行计划都是最优化的,不过在某些特定场景下,执行计划可能不是最优化。

比如:表t1经过大量的频繁更新操作,(UPDATE,DELETE,INSERT),cardinality已经很不准确了,这时候刚好执行了一条SQL,那么有可能这条SQL的执行计划就不是最优的。为什么说有可能呢?

来看下具体演示

譬如,以下两条SQL,

A:

select* from t1 where f1= 20;

B:

select* from t1 where f1= 30;

如果f1的值刚好频繁更新的值为30,并且没有达到MySQL自动更新cardinality值的临界值或者说用户设置了手动更新又或者用户减少了sample page等等,那么对这两条语句来说,可能不准确的就是B了。

这里顺带说下,MySQL提供了自动更新和手动更新表cardinality值的方法,因篇幅有限,需要的可以查阅手册。

那回到正题上,MySQL 8.0带来了几个HINT,我今天就举个index_merge的例子。

示例表结构:

mysql> desc t1;+------------+--------------+------+-----+---------+----------------+| Field| Type| Null| Key| Default| Extra|+------------+--------------+------+-----+---------+----------------+| id| int(11)| NO| PRI| NULL| auto_increment|| rank1| int(11)| YES| MUL| NULL||| rank2| int(11)| YES| MUL| NULL||| log_time| datetime| YES| MUL| NULL||| prefix_uid| varchar(100)| YES|| NULL||| desc1| text| YES|| NULL||| rank3| int(11)| YES| MUL| NULL||+------------+--------------+------+-----+---------+----------------+7 rows in set(0.00 sec)

表记录数:

mysql> select count(*) from t1;+----------+| count(*)|+----------+| 32768|+----------+1 row in set(0.01 sec)

这里我们两条经典的SQL:

SQL C:

select* from t1 where rank1= 1 or rank2= 2 or rank3= 2;

SQL D:

select* from t1 where rank1=100 and rank2=100 and rank3=100;

表t1实际上在rank1,rank2,rank3三列上分别有一个二级索引。

那我们来看SQL C的查询计划。

显然,没有用到任何索引,扫描的行数为32034,cost为3243.65。

mysql> explain format=json select* from t1 where rank1=1 or rank2= 2 or rank3= 2\G*************************** 1. row***************************EXPLAIN:{"query_block":{"select_id": 1,"cost_info":{"query_cost":"3243.65"},"table":{"table_name":"t1","access_type":"ALL","possible_keys": ["idx_rank1","idx_rank2","idx_rank3" ],"rows_examined_per_scan": 32034,"rows_produced_per_join": 115,"filtered":"0.36","cost_info":{"read_cost":"3232.07","eval_cost":"11.58","prefix_cost":"3243.65","data_read_per_join":"49K"},"used_columns": ["id","rank1","rank2","log_time","prefix_uid","desc1","rank3" ],"attached_condition":"((`ytt`.`t1`.`rank1`= 1) or(`ytt`.`t1`.`rank2`= 2) or(`ytt`.`t1`.`rank3`= 2))"}}}1 row in set, 1 warning(0.00 sec)

我们加上hint给相同的查询,再次看看查询计划。

这个时候用到了index_merge,union了三个列。扫描的行数为1103,cost为441.09,明显比之前的快了好几倍。

mysql> explain format=json select/*+ index_merge(t1)*/* from t1 where rank1=1 or rank2= 2 or rank3= 2\G*************************** 1. row***************************EXPLAIN:{"query_block":{"select_id": 1,"cost_info":{"query_cost":"441.09"},"table":{"table_name":"t1","access_type":"index_merge","possible_keys": ["idx_rank1","idx_rank2","idx_rank3" ],"key":"union(idx_rank1,idx_rank2,idx_rank3)","key_length":"5,5,5","rows_examined_per_scan": 1103,"rows_produced_per_join": 1103,"filtered":"100.00","cost_info":{"read_cost":"330.79","eval_cost":"110.30","prefix_cost":"441.09","data_read_per_join":"473K"},"used_columns": ["id","rank1","rank2","log_time","prefix_uid","desc1","rank3" ],"attached_condition":"((`ytt`.`t1`.`rank1`= 1) or(`ytt`.`t1`.`rank2`= 2) or(`ytt`.`t1`.`rank3`= 2))"}}}1 row in set, 1 warning(0.00 sec)

我们再看下SQL D的计划:

不加HINT,

mysql> explain format=json select* from t1 where rank1=100 and rank2=100 and rank3=100\G*************************** 1. row***************************EXPLAIN:{"query_block":{"select_id": 1,"cost_info":{"query_cost":"534.34"},"table":{"table_name":"t1","access_type":"ref","possible_keys": ["idx_rank1","idx_rank2","idx_rank3" ],"key":"idx_rank1","used_key_parts": ["rank1" ],"key_length":"5","ref": ["const" ],"rows_examined_per_scan": 555,"rows_produced_per_join": 0,"filtered":"0.07","cost_info":{"read_cost":"478.84","eval_cost":"0.04","prefix_cost":"534.34","data_read_per_join":"176"},"used_columns": ["id","rank1","rank2","log_time","prefix_uid","desc1","rank3" ],"attached_condition":"((`ytt`.`t1`.`rank3`= 100) and(`ytt`.`t1`.`rank2`= 100))"}}}1 row in set, 1 warning(0.00 sec)

加了HINT,

mysql> explain format=json select/*+ index_merge(t1)*/* from t1 where rank1=100 and rank2=100 and rank3=100\G*************************** 1. row***************************EXPLAIN:{"query_block":{"select_id": 1,"cost_info":{"query_cost":"5.23"},"table":{"table_name":"t1","access_type":"index_merge","possible_keys": ["idx_rank1","idx_rank2","idx_rank3" ],"key":"intersect(idx_rank1,idx_rank2,idx_rank3)","key_length":"5,5,5","rows_examined_per_scan": 1,"rows_produced_per_join": 1,"filtered":"100.00","cost_info":{"read_cost":"5.13","eval_cost":"0.10","prefix_cost":"5.23","data_read_per_join":"440"},"used_columns": ["id","rank1","rank2","log_time","prefix_uid","desc1","rank3" ],"attached_condition":"((`ytt`.`t1`.`rank3`= 100) and(`ytt`.`t1`.`rank2`= 100) and(`ytt`.`t1`.`rank1`= 100))"}}}1 row in set, 1 warning(0.00 sec)

对比下以上两个,加了HINT的比不加HINT的cost小了100倍。

总结下,就是说表的cardinality值影响这张的查询计划,如果这个值没有正常更新的话,就需要手工加HINT了。相信MySQL未来的版本会带来更多的HINT。

mysql数据库优化和mysql 优化包括哪些内容的问题分享结束啦,以上的文章解决了您的问题吗?欢迎您下次再来哦!

服务器关机?浪潮服务器如何关机syslog日志服务器搭建,如何搭建syslog日志服务器