sql优化小记

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  北京今天刮大风 

网上看到一个问题 贴下截图


图1


图2

三者的区别

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语句

你可能感兴趣的:(sql优化小记)