mysql优化
1)left join 左连接 驱动表是右表; 右表 加索引,其他类似
2)join优化
永远用小结果集驱动大的结果集
优先优化NestedLoop的内层循环
保证join语句中被驱动表上join条件字段已经被索引
3)其他优化
当无法保证被驱动表的join条件字段被索引且内存资源充足的前提下,不要太吝啬joinBuffer的设置
尽量使用覆盖索引(只返回索引的查询(索引列和查询列一致)),减少select*
!=,is not null ,is null 会导致索引失效
字符串不加单引号索引失效
少用or
索引失效
网上看的顺口溜:
带头大哥不能死
中间兄弟不能断
索引列上少计算
范围之后全失效
like 百分加右边
group by 表面上叫分组,分组之前必排序 会产生临时表
类似order by
exists 可以理解为 将主查询的数据 放到主查询中做条件验证 根据验证结果(true or false)
来决定主查询的数据结果是否得以保留
order by 优化
尽可能在索引列上完成排序操作 遵照索引最佳做前缀法则
如果排序字段不在索引列上 filesort有2种算法
单路排序 多路排序
在sort_buffer中 方法b(多路算法法)比方法a(单路算法)要多占用很多空间,因为方法b是把所有字段都取出
所以有可能取出数据的总大小超出了sort_buffer的容量,导致每次只能读取sort_buffer
容量大小的数据 进行排序(创建temp文件 多路合并) 排完再取
sort_buffer大小的容量大小 再排... 从而多次I/O
本来想省一次I/O 反而导致了大量的I/O 反而得不偿失
优化策略:增大 sort_buffer_size 参数的设置
增大max_length_for_sort_data参数设置
少写select *
why
----------
为排序使用索引
1)mysql 2中排序方式:文件排序(using filesort),扫描有序索引排序(using index)
2)mysql能为排序与查询使用相同的索引
2020-04-16 19:23 北京今天刮大风
网上看到一个问题 贴下截图
三者的区别
using index:使用覆盖索引的时候就会出现
using where:在查找使用索引的情况下,需要回表去查询所需的数据
using index condition:查找使用了索引,但是需要回表查询数据
using index & using where:查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据
以上四点就能看出它们之前的区别,
或许有部分人都存在疑惑using index & using where和using index condition那个比较好,
从上面的的解释中就能看出是前者比较好,毕竟不需要回表查询数据,效率上应该比较快的
mysql 覆盖索引:
覆盖索引的定义:
如果一个索引包含(或覆盖)所有需要查询的字段的值,称为‘覆盖索引’。即只需扫描索引而无须回表。
只扫描索引而无需回表的优点:
1.索引条目通常远小于数据行大小,只需要读取索引,则mysql会极大地减少数据访问量。
2.因为索引是按照列值顺序存储的,所以对于IO密集的范围查找会比随机从磁盘读取每一行数据的IO少很多。
3.一些存储引擎如myisam在内存中只缓存索引,数据则依赖于操作系统来缓存,因此要访问数据需要一次系统调用
4.innodb的聚簇索引,覆盖索引对innodb表特别有用。(innodb的二级索引在叶子节点中保存了行的主键值,所以如果二级主键能够覆盖查询,则可以避免对主键索引的二次查询)
覆盖索引必须要存储索引列的值,而哈希索引、空间索引和全文索引不存储索引列的值,所以mysql只能用B-tree索引做覆盖索引。
当发起一个索引覆盖查询时,在explain的extra列可以看到using index的信息
理解MySQL回表:
回表就是先通过数据库索引扫描出数据所在的行,再通过行主键id取出索引中未提供的数据,即基于非主键索引的查询需要多扫描一棵索引树。
慢查询日志:
--查看慢查询日志是否开启 及文件位置
show variables like 'slow_query%';
--默认慢查询时间 10s
show variables like 'long_query_time';
--将 slow_query_log 全局变量设置为“ON”状态 ,临时生效,mysql重启后就会失效
set global slow_query_log='ON';
--设置慢查询时间
set global long_query_time=3
换新绘画才能看到生效;
-- show profiles
show VARIABLES like 'profiling'
--默认OFF
show profiles;
/*Query_ID为#3步骤中show profiles列表中的Query_ID*/
show profile cpu,block io for query 132;
#1.show profile默认是关闭的,并且开启后只存活于当前会话,也就说每次使用前都需要开启。
#2.通过show profiles查看sql语句的耗时时间,然后通过show profile命令对耗时时间长的sql语句进行诊断。
#3.注意show profile诊断结果中出现相关字段的含义,判断是否需要优化sql语句