1、数据库优化可以从以下几个方面进行:
2、项目中,优化mysql之前,首先要开启慢查询日志,在分析慢查询日志.
1,查看所有日志状态: show variables like '%quer%';
2,查看慢查询状态:show variables like 'show%'
linux启用MySQL慢查询
代码如下 vim /etc/my.cnf
[mysqld]
slow-query-log = on # 开启慢查询功能
slow_query_log_file = /usr/local/mysql/data/slow-query.log # 慢查询日志存放路径与名称
long_query_time = 5 # 查询时间超过5s的查询语句
log-queries-not-using-indexes = on # 列出没有使用索引的查询语句
Windows下开启MySQL慢查询
MySQL在Windows系统中的配置文件一般是是my.ini找到[mysqld]下面加上
补充:
在my.cnf或者my.ini中添加log-queries-not-using-indexes参数,表示记录下没有使用索引的查询。比如:
代码如下 log-slow-queries=/data/mysqldata/slowquery.log # 慢查询日志存放路径与名称
long_query_time=5 # 查询时间超过5s的查询语句
log-queries-not-using-indexes # 列出没有使用索引的查询语句
![](https://i-blog.csdnimg.cn/blog_migrate/925cdf798555a0b725e51b86b8b24553.png)
3、如何分析sql查询
explain返回各列的含义
extra列需要注意的返回值
Using filesort:看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行
Using temporary看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上
3.1 MySql内部函数explain(查询sql的执行计划)使用方法以及返回各列的含义
explain返回各列的含义
table:显示这一行的数据是关于哪张表的
type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、index 和ALL
possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。
key:实际使用的索引。如果为NULL,则没有使用索引。
keyjen:使用的索引的长度。在不损失精确性的情况下,长度越短越好
ref:显示索引的哪一列被使用了,如果可能的话,是一个常数
rows: MYSQL认为必须检查的用来返回请求数据的行数
实例1:mysql函数【max()】,最后一位注册用户的信息
进行查询操作,图一是没有加索引,图二是加了索引的,查询出来的type和rows字段也不相同。(参照上图字段段含义)
图一:
![](https://i-blog.csdnimg.cn/blog_migrate/0e2414149314455486f0ba0afedb9159.png)
图二:
![](https://i-blog.csdnimg.cn/blog_migrate/8b103d4dd14e6834c5e572fe49033fa7.png)
实例2: mysql函数【count() 】,获取注册用户男女人数
显然图三不是这个查询方法不是咱们想要的结果,图四和图五也一样,利用count()函数的特性null不统计,得到了我们想要的结果(图六)。
图三:
![](https://i-blog.csdnimg.cn/blog_migrate/9d539eae745da1d807026064573279ac.png)
图四:
![](https://i-blog.csdnimg.cn/blog_migrate/d4bd8af994c24a311bda8a1347898568.png)
图五:
![](https://i-blog.csdnimg.cn/blog_migrate/0e4afbf2784a7c4a5b71fab1da328193.png)
图六:
![](https://i-blog.csdnimg.cn/blog_migrate/2e1ef2cc52b56026a10ae68cb908c4c8.png)
3.2 子查询的优化,通常情况下把子查询优化为join查询,但在优化的时候需要注意关联建是否有一对多的关系,要特别注意重复数据
![](https://i-blog.csdnimg.cn/blog_migrate/548c231db425b02607d41ced61cd3e81.png)
实例3:如图七和图八
图七:
![](https://i-blog.csdnimg.cn/blog_migrate/4e4f09bb93df475378f9c9247e45db98.png)
图八:
![](https://i-blog.csdnimg.cn/blog_migrate/80e98488289d945fd54d59d00dd23d47.png)
3.3 GROUP BY的优化
![](https://i-blog.csdnimg.cn/blog_migrate/517961d9642726b6f582ca2c44c1c014.png)
![](https://i-blog.csdnimg.cn/blog_migrate/021c921380c7a0322794ce8dfcf16900.png)
实例4:获取每个用户爱好的数量。使用sql执行计划来排查,图九使用GROUP BY查询,关联的表会产生临时表和按照文件排序,sql优化之后(图十)就直接按照索引来查询,避免临时表的产生和文件形式排序。在数据量大的时候会大大减少对服务器的IO访问。
图九:
![](https://i-blog.csdnimg.cn/blog_migrate/707f1f34a0a976b5e22703e9686f7ec8.png)
图十:
![](https://i-blog.csdnimg.cn/blog_migrate/dc806d6d65c7a1c7fc482d708d1812fb.png)
实例5:使用LIMIT一般都伴随着ORDER BY(如图十一),如果是没有索引的字段排序的的话会按照文件排序,全表查询会加大对服务器IO的访问。
图十一:
![](https://i-blog.csdnimg.cn/blog_migrate/36374acfbc33f0a11cf68abf6413778f.png)
优化方案一:使用主键进行排序,不会造成全表扫描,会减少对服务器IO的访问。但是还有一个问题,当所查询的条数越往后,所扫描的条数也会越多(如图十三)
图十二:
![](https://i-blog.csdnimg.cn/blog_migrate/f726dc40e23ae9f37c5a9db71ca2c151.png)
图十三:
![](https://i-blog.csdnimg.cn/blog_migrate/ffd4b5a687aa629f90cfeaef38dce530.png)
优化方案二:可以获取上一个主键的id来做一个范围查询来减少对服务器IO的访问(如图十四),但是因此还会出现另一个问题,要保证主键ID是连续的,当主键ID中间有缺少,会对我们查询出来的数据不对。
![](https://i-blog.csdnimg.cn/blog_migrate/df7bbc88799af64300c5e5deab322513.png)
优化方案三:可以添加一个字段用于LIMIT查询,再加上索引,就和主键id产生同样的效果,但是这样会产生很多麻烦。
4 .1、如何选择合适的列建立索引
![](https://i-blog.csdnimg.cn/blog_migrate/7c6851e90e1facbf1e396d446d0ee614.png)
说明:
1、如果一个索引可以包含所有字段的话,就称之为覆盖索引。当一张表里的数据少的话,就可以使用覆盖索引,这样就可以读取索引而不用读取表了。
2、索引字段越小越好,因为数据库里的数据是已页存储的,如果IO一次读取一页的数据很多,这样的话就可以提高服务器IO的效率。
3、在建立联合索引的时候,一定要把离散度大的放在前面,这样的话效果比较好
实例6:通过count函数统计唯一值,值大的离散度就大,也就是说u_pass的离散度比大u_name,所以应该使用index(u_pass,u_name)
![](https://i-blog.csdnimg.cn/blog_migrate/ecf5888d0f153832908520abf4d72438.png)
4.2、索引的维护和优化
4.2.1重复索引
![](https://i-blog.csdnimg.cn/blog_migrate/1cf62d4399d06c650a8405fade368766.png)
4.2.2冗余索引
![](https://i-blog.csdnimg.cn/blog_migrate/ce8454571499ceb022e219ac0f6200d6.png)
4.2.3检查重复及冗余索引的工具
![](https://i-blog.csdnimg.cn/blog_migrate/390111efa18123babea5634f354553c3.png)
4.2.4删除不用的索引
![](https://i-blog.csdnimg.cn/blog_migrate/f81a245e8e247a761f390eba61c802fc.png)
说明:由于业务变更有些原来使用的索引现在不使用了也是需要清除的,这也是索引优化的一个方面了!
注意:再次的强调SQL和索引的优化对于数据库的优化是相当重要的,这一层的优化如果做好了,其他的优化也能起到一些作用否则其他的优化所能起到的作用是微乎其微的,这一层的优化也是成本最低效果最好的一层了,所以对于数据库的优化最好重点放在这一层。
注意:再次的强调SQL和索引的优化对于数据库的优化是相当重要的,这一层的优化如果做好了,其他的优化也能起到一些作用否则其他的优化所能起到的作用是微乎其微的,这一层的优化也是成本最低效果最好的一层了,所以对于数据库的优化最好重点放在这一层。
5、数据库结构优化
5.1选择合适的数据类型
数据类型的选择,重点在于
合适二字,如何确定选择的数据类型是否合适?
1.使用可以存下你的数据的最小的数据类型。
2.使用简单的数据类型。Int要比varchar类型在mysql处理上简单。
3.尽可能的使用not null定义字段。
4.尽量少用text类型,非用不可时最好考虑分表。
实例:i
nt、bigint、smallint 和
tinyint范围
使用整数数据的精确数字数据类型。bigint从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据(所有数字)。存储大小为 8 个字节。int从 -2^31 (-2,147,483,648) 到 2^31 - 1 (2,147,483,647) 的整型数据(所有数字)。存储大小为 4 个字节。int 的 SQL-92 同义字为 integer。smallint从 -2^15 (-32,768) 到 2^15 - 1 (32,767) 的整型数据。存储大小为 2 个字节。tinyint从 0 到 255 的整型数据。存储大小为 1 字节。注释在支持整数值的地方支持 bigint 数据类型。但是,bigint 用于某些特殊的情况,当整数值超过 int 数据类型支持的范围时。在数据类型优先次序表中,bigint 位于 smallmoney 和 int 之间。
实例:时间使用int类型
![](https://i-blog.csdnimg.cn/blog_migrate/0cddd2494e627c07c87fbdc8a12127ee.png)
实例:IP地址使用bigint类型
![](https://i-blog.csdnimg.cn/blog_migrate/e1fc13038031528aaa7f24cec77917b1.png)
5.2 表的范式化
什么是范式化?
![](https://i-blog.csdnimg.cn/blog_migrate/2fdd0d0995db3af95b75a29af4522ab6.png)
不符合第三范式的要求会出现的问题
![](https://i-blog.csdnimg.cn/blog_migrate/1070f047d4565ce4ddc2fe870a4b4522.png)
实例:
![](https://i-blog.csdnimg.cn/blog_migrate/0fbd1a4343a4367f9fdad45122355353.png)
5.3 表的反范式化的使用
![](https://i-blog.csdnimg.cn/blog_migrate/04f2d4ca1cf77ebc682af3cc38a40942.png)
如我要查询订单商品表的下单人,电话,地址,订单id和下单时间sql语句如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6783225f55a7b4c38936fd0662c4d1b9.png)
使用反范式化的表结构
![](https://i-blog.csdnimg.cn/blog_migrate/f355a92f58a9f71c8b4dc541426da59a.png)
sqi语句的查询效率也会提升很多,数据库表结构的设计对sql的优化也起到了很大的作用
![](https://i-blog.csdnimg.cn/blog_migrate/4ae46c938b508a3aa4bc04e7911fd466.png)
5.4 表的垂直拆分
![](https://i-blog.csdnimg.cn/blog_migrate/98c901e8df7c8ecd0147266e0b333f43.png)
5.5 表的水行拆分
当表的数据比较多的时候,可以选择将表进行水平拆分,水平拆分的本质并没有改变表的结构仅是将原本存放在同一个表中的数据放到了多个结构一样的表中。
水平拆分的方法:
![](https://i-blog.csdnimg.cn/blog_migrate/75c3fab9e5917e38e177d99d23b2e810.png)
6 系统配置优化
6.1操作系统优化
![](https://i-blog.csdnimg.cn/blog_migrate/5bad96f1b6d7103cea7109064e9cd9fe.png)
![](https://i-blog.csdnimg.cn/blog_migrate/fa6da109dc8c4725af9cac4f66276849.png)
6.2 MySql配置优化
![](https://i-blog.csdnimg.cn/blog_migrate/1913f36cf7c6ad171fe960b762f7c671.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b1ec49b95b61803893db6943e1b34ef3.png)
SELECT engine,ROUND(SUM(data_length+index_length)/1024/2014,1) AS "Total MB" FROM INFORMATION_SCHEMA.TABLES WHERE table_schema not in ("information_schema","performance_schema") GROUP BY ENGINE;
mysql常用配置参数1
![](https://i-blog.csdnimg.cn/blog_migrate/02549c57cbd0738fb8aa3f2b5f76a986.png)
mysql常用配置参数2
![](https://i-blog.csdnimg.cn/blog_migrate/4ffc2c618cec78d993612d32e471b450.png)
mysql常用配置参数3
![](https://i-blog.csdnimg.cn/blog_migrate/e6412112451b55d31358f1bf58fd9bb2.png)
mysql常用配置参数4
![](https://i-blog.csdnimg.cn/blog_migrate/55950000e07db8cc12538e00e28883b9.png)
mysql常用配置参数5
![](https://i-blog.csdnimg.cn/blog_migrate/8604ff9a282971d10d86f9377ee35bab.png)
6.3 MySql第三方配置工具
https://tools.percona.com/wizard
配置MySQL的配置文件使用工具更方便,主要就是调整配置的参数,值调整成什么样的参数才是合适的,估计需要补充各种基础知识不是三言两语说的清楚的。
就是将文本的配置方式变成了界面式的配置方式,不过经验在此时就非常的重要了,否则压根判断不出什么样的配置才是适合的配置!
就是将文本的配置方式变成了界面式的配置方式,不过经验在此时就非常的重要了,否则压根判断不出什么样的配置才是适合的配置!
7 服务器硬件优化
![](https://i-blog.csdnimg.cn/blog_migrate/0ed6775559707d84ea5c1b608c2fcb4b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1729fdf7b1fd9d970e976c5bd8b44ca1.png)
模拟数据库数据和sql语句下载:
链接:https://pan.baidu.com/s/1c1xe0WQttP9gA_uUcOVHDA
密码:rnjh