数据库优化及执行计划(explain)详解

1.什么是索引

答:索引是一种能快速查找的数据结构

2.索引都分为什么类型

答:BTree索引、Hash索引、full-text全文索引、R-tree索引,B树索引结构是二叉树

3.索引的优势和劣势

答:优势:(1)提高数据检索的效率,降低数据库的io成本
(2)降低数据库的排序的成本,降低CPU的消耗
劣势:(1)索引实际上也是一张表 ,该表保存了主键与索引字段,并指向实体表的记录,所以索引也是要占用空间的
(2)索引虽然大大提高了查询速度,同时却会降低更新表的速度,如对标进行insert、update和delete。因为更新表时,不仅要跟新数据,还要保存一下索引文件。每次更新添加的索引列的字段。都会调整因为更新所带来的的键值变化后的索引信息。

4.索引分为哪几类

答:单值索引,唯一索引,复合索引

5.创建、删除、查看索引

答:创建:create[unique] index indexName on mytable(columnName(lengrh));
alter mytable add [unique] index
[indexName] on (columnName(length));
删除:drop index [indexName] on mytabke;
查看:show index from table_name\G
*注 [unique] 代表唯一索引

6.哪些情况需要建立索引,那些情况不需要建立索引

答:需要建立索引:(1)主键自动建立唯一索引
(2)频繁作为查询条件的字段
(3)外键关系建立索引
(4)查询中排序的字段
(5)需要统计和分组的字段
不需要建立索引:(1)频繁更新的字段
(2)where条件用不到的字段
(3)表的数据太少
(4)对某个数据列包含许多重复的内容,不要建立索引,比如性别列等

7.join语句的优化

答:(1)尽可能减少join中的NestedLoop的循环总次数,“永远小表驱动大表”
(2)优先优化NestedLoop的内层循环
(3)保证join语句中被驱动表上的join字段已经被索引
(4)当无法保证表被驱动表的join条件字段被索引且内存资源充足的前提下,不要太吝啬joinbuffer的设置

8.怎样避免索引失效

答:(1)全值匹配
(2)最佳左前缀法则--如果复合索引了多列,要遵守最左前缀法则。查询从索引的最左前列开始并且不跳过索引中的列
(3) 不要在where后面索引的列上做任何操作(计算、函数、(自动or手动)类型装换),会导致索引失效而转向全表扫描
(4)存储引擎不能使用索引中范围条件有变的列
(5)尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select*
(6)mysql在使用(!=或者<>)的时候无法使用索引会导致全表扫描
(7)is null,is not null也无法使用索引
(8)like以通配开头,mysql索引会失效变成全表扫描的操作
(9)字符串不加单引号索引失效
(10)少用or,用它来连接是会索引失效
*select name from table where name like ‘%xx%’ //如果name为索引列,不会破坏索引

9.explain相关字段分析

答:id:ID如果相同可以认为是一组,从上往下执行,在所有组中,id值越大,优先级越高,越先执行
type:访问类型 system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>
unique_subquery>index_subquery>range>index>ALL
常用的类型:system>const>eq_ref>ref>range>index>ALL
一般来说,至少要保证range级别,最好达到ref
const:表示通过索引一次找到了,const用于比较primary key或者unique做索引,因为只匹配一行数据,所以很快。如果将逐渐至于where列表中,mysql就能将该查询转换为一个常量。
eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条数据相匹配,常见u主键或唯一索引扫描
ref:非唯一性索引扫描,返回匹配某个单独值的所有行
range:只检索给定范围的行,使用一个索引来进行选择行。一般在where语句中出现<、>、in、between等的查询
index:index和ALL的区别为index类型遍历的事索引书,通常比ALL快
ALL:全表扫描找到匹配的行

10.SLECT_type字段说明:

答:select_type:(1)simple 简单的select查询,查询中不包含子查询和union
(2)primary 查询中若包含任何复杂的子部分,最外层则被标记为primary
(3)subquery:在select或where中包含子查询
(4)derived:在from列表中包含的子查询被标记为derived(衍生),mysql会递归执行这些子查询,把结果放在临时表里
(5)union:若第二个select出现在union之后,则被标记为union,若union包含from语句的子查询,外层select被标记为derived(衍生)
(6)union result :从union表获取结果的select

11.EXTRA字段值说明

(1)using index 说明mysql使用了覆盖索引,避免了回表操作,效率不错
(2)using where 表示根据过滤条件过滤结果集
(3)using file sort 表示排序的时候没有用到索引,不得不采取其他的排序方式,排序方式有内存排序、临时文件排序和双路排序法
(4)using temporay 表示用到了一张临时表。

12.查看慢日志是否开启

答:

show variables like '%low_query_log%';

13.开启慢日志记录

答:

set global slow_query_log=1;

永久生效:在my.cnf文件的[mysqld]底下增加slow_query_log=1 slow_query_log_file=/var/....(日志文件路径)

14.查看慢sql的记录超时时间

答:

show variables like 'low_query_time';

15.设置慢sql的超时记录时间

答:

set global slow_query_time=3;

16.慢日志分析工具mysqldumpslow

答:mysqld umpslow -s /var/....
s 表示按照何种方式进行排序
c 访问次数
i 锁定时间
r 返回记录
t 查询时间
al 平均锁定时间
ar 平均返回记录数
at 平均查询时间
-t 返回前面多少条数据
g 跟这则匹配 例如 left join

17.查看数据库锁的命令

答:show open tables;

18.数据库表加锁和解锁

答:lock table 表名 read(write),表名 read(write);

unlock tables;

读锁:当前用户不能查询其它表,只能查询加锁的表,不能更改任何数据,其他用户可以进行查询,但是更新,插入数据会阻塞等待释放锁。
写锁:当前用户可以查询、更新当前表,不能查看其它表,其它用户读取会出现阻塞等待释放锁。
简而言之,读锁会阻塞写,写锁会阻塞读写

19.如何分析表锁定

答:

show status like 'table%';

Table_locks_immediate:产生表级锁定的次数,表示可以立即获取锁的查询次数,每立即获取锁,值加1
Table_locaks_waited:出现表级锁竞争而发生等待的次数(不能立即获取锁的次数,没等待用一次锁,值加1),此值高说明存在着较严重的表级锁争用的情况;
此外,Myisam的读写锁调度室写优先,这也是myisam不适合做写为主表的引擎。因为写锁后,其它线程不能做任何操作,大量的更新回事查询很难得到锁,从而导致永远阻塞

20.InnoDB和MyISAM的不同点

答:innoDB支持事务,采用了行级锁 ,虽然在锁定机制的实现方面所带来的性能损耗可能比表级锁定会高一些,但是在整体并发处理能力方面要远远优于MyISAM的表级锁定。当系统并发量高的时候,InnoDB的整体性能和MyISAM相比就会有比较明显的优势
但是,InnoDB的行级锁同样也有脆弱的一面,当使用不当时,可能会让InnoDB的性能不仅不能比MyISAM的性能高,甚至可能会更差

21.事务的隔离级别

image.png

查看事务隔离级别:

show variables like 'tx_isolation';

22.关闭自动提交

答:

set autocommit =0;

23.行级锁的查询及分析

答:

show status like 'innodb_row_lock%';

状态说明:Innodb_row_lock_current_waits:当前正在等待锁定的数量
Innodb_row_lock_time:从系统启动到现在锁定总时间长度
Innodb_row_lock_avg:每次等待所花的平均时间
innodb_row_lock_waits:系统启动后到现在总共等待的次数

24.什么是间隙锁

答:当我们用范围条件,而不是相等条件检索,并请求共享或排他锁是,Innodb会给符合条件的已有数据记录的索引项加锁,对于键值在条件范围内但并不存在的记录,叫做“间隙”
InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁
危害:因为sql执行过程中通过范围查找的话,他会锁定整个范围内所有的索引建,即使这个键不存在。
间隙锁有一个比较致命的弱点,就是当锁定一个范围键值之后,即使某些不存在的键值也会被无辜锁定,而造成在锁定的时候无法插入锁定键值范围内的任何数据。

你可能感兴趣的:(数据库优化及执行计划(explain)详解)