面试准备之mysql优化

目录

一.创建数据库

二.mysql优化

1.开启慢日志

2.使用EXPLAIN对慢查询SQL或者对你刚写的SQL来进行分析

3.下面这些操作能让你的查询更加快速。

三.分区分表

四.主从复制,读写分离。

五.使用缓存。           


本来不打算写了的,但是不写看了一天觉得第二天可能就忘记了,这一天算是白看了。后面学习知识点的话,不打算以找工作为驱动点了,而是以写博客为驱动点了。

从四个大的方面来说

1.创建数据库

2.mysql优化

3.分区分表

4.主从复制,读写分离

5.加缓存

一.创建数据库

1.可以创建一些冗余字段,尽可能的避免连表查询。

2.对于一些固定的长度的字段或者经常要作为查询条件的字段可以使用定长来,例如电话号码就可以使用char(11)来建立,因为使用定长的好处在于数据库存取更加快捷。

char和varchar的不同点

char存储值是定长的,即使存储的值没有达到长度,它也会用空格填充,vachar不是定长的,长度会随着存储的字段的长度变化,一般都是存储的字段加一,这个多出来的一个是记录字段长度的。

3.尽量用not null,不要用null,因为null也会占用空间,需要一个额外字节作为判断是否为NULL的标志位,它会使索引、索引统计和值更加复杂,count(*)可以统计null的,但是count(phone)统计不到null。NOT IN子查询在有NULL值的情况下返回结果中带有NULL。

4.数据库建立的时候要符合范式要求。第一范式:每个列是原子性的,不可以再分。第二范式:每个列对主键是完全依赖,不存在部分依赖。第三范式:列对主键不存在传递依赖,例如不能存在主键A,C依赖B,B依赖A这种情况。

5.建立合适的索引。

二.mysql优化

1.开启慢日志

先查询慢日志是否开启

show variables like '%query%' 

现实结果

slow_query_log对应的值是ON的话代表慢日志开启,OFF代表慢日志是关闭的
slow_query_log_file就是记录慢日志的文件
long_query_time代表语句执行时间超过10秒就会被认定是慢查询

如果慢查询没有开启的话,可以执行下面这句话,并且将慢查询时间定义在2秒

set global slow_query_log='ON';
set global long_query_time=2;

例如我在数据库执行这样一句话,就会超过十秒,就会被记录到慢日志里面

select sleep(10),n.* from t_novel_main n;

在慢日志里面显示:

Time                 Id Command    Argument
# Time: 2019-11-30T14:20:52.603527Z
# User@Host: root[root] @ localhost [127.0.0.1]  Id:     9
# Query_time: 10.002048  Lock_time: 0.000081 Rows_sent: 1  Rows_examined: 1
use test;
SET timestamp=1575123652;
select sleep(10),n.* from t_novel_main n;

当然还可以使用日志分析工具mysqldumpslow对慢查询进行分析,分析出出现最多的慢查询SQL。

2.使用EXPLAIN对慢查询SQL或者对你刚写的SQL来进行分析

explain select * from tbl_user_no_part where id >= (select id from tbl_user_no_part limit 4000000 ,1) limit 20


解释几个比较重要的字段
id:表示查询的顺序,如果select_type不一样,id越大越先执行
type:表示用到了什么类型的索引:

         const:表示在where条件中用到了主键或者唯一索引在, "主键" 或 "唯一" 索引的所有部分与常量值进行比较,只返回一条数据。

         eq_ref:用于联表查询的情况,按联表的主键或唯一键联合查询。

         ref:表示查询条件中用到了非唯一索引。

         rang:表示查询条件中用到了索引进行范围查询。

         index:表示通过扫描整个索引文件就能查询出结果,如果查询出的字段就在建立了索引,但不带where条件的话就是这样的          (也就是说虽然all和Index都是读全表,但index是从索引中读取的,而all是从硬盘读取的)。

         ALL:扫描整个表查询出来的。

        当type是index和ALL的时候就需要注意了,看SQL是否有优化的地方。

possible_keys:可能会被用到的索引。

key:实际用到的索引。

rows:扫描到的行数。

Extra:表示一些额外的信息。

            Using index:表示用到了覆盖索引。
            Using where:表示用到了where条件过滤。
            Using filesort:表示用到了外部排序,不是通过索引直接返回排序结果的排序。

通过explain我们就知道sql用到了什么索引,以及扫描了多少行,这样可以便于我们作出更好的调整。
这个是对explain更详细的解读:https://blog.csdn.net/why15732625998/article/details/80388236

3.下面这些操作能让你的查询更加快速。

    (1) 不要用select * from ;
    (2) 如果确定查询出来的是一条数据的话,就应该在最后面加上limit 1;
    (3)尽量用inner join 代替子查询。
    (4)or条件两边都是索引的话,所以才能生效,最好是能用union all代替。
    (5)注意in 和 exist的使用,in的话先查询子表,exist的话先查询外表,所以当子查询数据较多的时候用exist,当外查询数据较多的时候用使用in,如果是not in 和not exist 的时候使用not exist ,not in 会使索引失。
    (6)如果是分页的话可以使用
    select * from `t_channel_total_every` where id>=(select id from t_channel_total_every limit 500000,1) limit 100;
    来代替select * from t_channel_total_every limit 500000,100;
    但是上面的确定有提升,但是提升效果不大。如果下面id是连续的话,可以使用select * from t_channel_total_every where id>500000,100  来执行,但是由于有删除的话,id不连续,这样查询也会有问题,在网上找了大半天都没有找到一个能很好解决大数据分页的答案的,都是抄来抄去,虽然我也是抄。

4.下面这些操作可能会让索引失效。
   (1).如果在where条件中索引存在类型强转的,例如明明是字符串类型的,但是没有加单引号,或者是整数类型的,但是加了单引号,这样会使索引失效。
   (2).使用联合索引的时候注意最左前缀原则。
   (3).使用like查询的时候注意%不要放在最左边。
   (4).如果用or进行查询的话,左右两边都要使用索引才能生效。
   (5).在查询条件中对查询条件计算或者使用函数会使索引失效。
   (6).在查询条件上使用!= 或者<>会使索引失效。
   (7).如果使用索引的查询代价太大,会改成全表扫描。

三.分区分表

分区分表这个太有难度了,很难把控,要是使用不当很容易引起其他的问题。
分区有五种分区方式,这里只介绍四种:rang,list,hash,key,需要注意的是不能使用非主键或者唯一索引进行分区,也就是分区字段里面必须包含主键或者唯一索引。
rang分区:按某一个值的的范围进行分区

partition by range (store_id) (
   partition p0 values less than (10),
   partition p1 values less than (20),
   partition p2 values less than (30)
);

list分区:按值分区,比较适合对一些固定的离散值进行分区

partition by list(category)(
    partition p0 values in (3,5),
    partition p1 values in (1,10),
    partition p2 values in (4,9),
    partition p3 values in (2)
);

hash分区:对某列或者几列进行hash计算,然后取模来分区

partition by hash (store_id) partitions 4;

key区分

PARTITION BY LINEAR Key(email)  PARTITIONS 4;

KEY分区和HASH分区相似,但是KEY分区支持除text和BLOB之外的所有数据类型的分区,而HASH分区只支持数字分区,KEY分区不允许使用用户自定义的表达式进行分区,KEY分区使用系统提供的HASH函数进行分区。当表中存在主键或者唯一键时,如果创建key分区时没有指定字段系统默认会首选主键列作为分区字列,如果不存在主键列会选择非空唯一键列作为分区列,注意唯一列作为分区列唯一列不能为null。

四.主从复制,读写分离。

五.使用缓存。           

 

发布了89 篇原创文章 · 获赞 110 · 访问量 23万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章