sql-知识

一、mysql

1. mysql 查看sql的执行计划:explain + sql

explain SELECT * FROM teacher t WHERE name = '石老师'

在这里插入图片描述

重要列含义
id执行的先后顺序,越大越先执行
type索引级别,从优到差为:system>const>eq_ref>ref>range>index>all
key使用了哪个索引
ref哪个列使用了索引
rows查询出了多少列,越少越好,可以看出条件的过滤性如何
extra其他信息,从优到差为:using index > using filesort (使用文件排序)> using temporary(建立临时表)

ps:其中,type,各级别解释为:

代码含义
system 、const只有一条数据时
eq_ref查询条件是唯一索引
ref查询条件是普通索引
range查询条件是范围索引,如 < > in
index全索引扫描
all全表扫描

一般来说,查询达到 range级别即可, ref 级别更佳
extra 里 出现这两个要警惕,极大影响性能,多数情况下是order by 和 group by 没有命中索引导致的
using filesort (使用文件排序), using temporary(建立临时表)

2.mysql index 优化 注意点

  1. 范围查询和order by 不可兼得: 复合索引,range查询后的索引会失效
create index idx_teacher_name_age_courseNum on teacher(name,age,courseNum);

如果使用以下查询:
select * from teacher where name = '1' and age = 1 order by courseNum
可以使用索引
 
如果使用以下查询:
select * from teacher where name = '1' and age > 1 order by courseNum
则索引失效!!!

解决方法:建立索引时,跳过需要范围查询的字段,以求order by 命中索引
create index idx_teacher_name_courseNum on teacher(name,courseNum);

3. 小表驱动大表原则:

规则如下:
1.当使用left join时,左表是驱动表,右表是被驱动表 ;
2.当使用right join时,右表时驱动表,左表是驱动表 ;
3.当使用inner join时,mysql会选择数据量比较小的表作为驱动表,大表作为被驱动表 ;

原理类似循环,小循环在外,大循环在内,以求 通过减少表连接创建的次数,加快查询速度 。

例如:left join 时,应该小表在前,大表在后,同时在大表的联结字段上建立索引。

select * from categary c left join book b on c.id on book.cid;
此时 左表(categary)为小表,右表(book)为大表,小表驱动大表,且应在右表(book)的联结字段(cid)上建立索引

索引优化口诀:

全值匹配我最爱,最左前缀要遵守;
带头大哥不能死,中间兄弟不能断;
索引列上少计算,范围之后全失效;
Like百分写最右,覆盖索引不写星;
不等null值还有or,索引失效要少用;
VAR引号不可丢,SQL高级也不难!

4. like 百分号在最右(左匹配)的情况下,可以使用索引。如果要使用全匹配(左右都有百分号),则需要查询的列被索引覆盖

不可以使用索引:
explain SELECT * FROM teacher t WHERE name like '%石老师%'

可以使用索引:(索引覆盖)
explain SELECT name FROM teacher t WHERE name like '%石老师%'

可以使用索引:(左匹配)
explain SELECT * FROM teacher t WHERE name like '石老师%'

5. order by 后的想要使用组合索引排序的话,order by 也需要遵循从左往右(中间兄弟不能断)的原则

create table test01(id,t1,t2,t3,t4,t5,t6);
create index idx_test01_t1234 on test01(t1,t2,t3,t4);

命中索引:t1,t2. t3索引用于排序
explain select * FROM  test01 WHERE t1='1' and t2='2' order by t3;

命中索引:t1,t2. 由于没有t3,t4的排序会使用 filesort
explain select * FROM  test01 WHERE t1='1' and t2='2' order by t4;

命中索引:t1,t2. t3,t4 索引用于排序
explain select * FROM  test01 WHERE t1='1' and t2='2' order by t3,t4;

命中索引:t1,t2.  由于t4,t3 顺序反了,无法索引,产生 filesort
explain select * FROM  test01 WHERE t1='1' and t2='2' order by t4,t3;

6.关于 in , exist , not in, not exist

这里简单的给自己做个记录:
exist和in的区别:
select * from a where id in (select id from b) ;
select * from a where id exists (select id from b) ;
对于这样的sql查询同一个库,结果是一样的,但是查询速度对于不同情况,
差别较大;
使用in ,sql语句是先执行子查询,也就是先查询b表,在查a表,
而使用exists是先查主表a ,再查字表b; 对于主表数据较多时,我们
使用in速度比exist更快,反之,从表b较大时,使用exist插叙速度更快(都会使用索引),
如果使用的是not in与not exists,直接使用not exists,因为not in 会进行全表扫描
不走索引,not exists会走索引。

7. order by 使用索引举例

在这里插入图片描述

8. 开启慢sql日志

查询开关和log文件的位置

show variables like '%slow_query_log%'

在这里插入图片描述

可以看到slow_query_log的值是OFF,也就是mysql默认是不启用慢查询日志的。

这里还有个long_query_time,默认是10秒,也就是超过了10秒即为慢查询。

开启:

打开
set global slow_query_log='ON';
定义慢sql时间为5set global long_query_time= 5;

ps:这种设置方式是临时的,永久设置需要改配置文件

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值