该文章借鉴了不一样平台对知识点的描述。java
InnoDB:mysql
MySIAM:sql
操做区别:数据库
选择:缓存
索引是对数据库表中一或多个列的值进行排序的结构,是帮助MySQL高效获取数据的数据结构安全
(数据库是磁盘文件,磁盘IO 的代价较高,因此采用索引减小IO 次数)服务器
Mysql 中经常使用的索引有B+ 树索引(包括普通索引、惟一索引、主键索引),哈希索引,全文索引,R-TREE 索引(空间索引,主要用于地理空间数据类型,不多使用)。网络
Mysql 传统意义上的索引为B+ 树索引,B+ 树索引的本质就是B+ 树在数据库中的实现,因为B+ 树的高扇出性,数据库中的B+ 树的高通常为2-4层,所以查找某一键值的行记录只需2-4次IO,大概0.02~0.04秒。session
(扇出性:是指该模块直接调用的下级模块的个数。扇出大表示模块的复杂度高,须要控制和协调过多的下级模块)
数据结构
B+ 树索引
主要分为汇集索引和辅助索引。
汇集索引是根据每张表的主键建造的一棵B+ 树,叶子节点中存放的是整张表的行记录。一张表只能有一个汇集索引。由于汇集索引在逻辑上是连续的,因此它对于主键的排序查找和范围查找速度很是快。
辅助索引与汇集索引不一样的地方在于,辅助索引不是惟一的,它的叶子节点只包含行记录的部分数据以及对应汇集索引的节点位置。经过辅助索引来查找数据时,先遍历辅助索引找到对应主键索引,再经过主键索引查找对应记录。
在MYISAM 中主键索引和辅助索引都至关上述辅助索引,索引页中存放的是主键和指向数据页的偏移量,数据页中存放的是主键和该主键所属行记录的地址空间。惟一的区别是MYISAM 中主键索引不能重复,辅助索引能够。
从使用上来讲还有联合索引和覆盖索引。
联合索引是指对表上的多个列进行索引。它对对应多个列的指定获取比较快。另一个好处是联合索引对第二个键已经排好序了,因此对两个列的排序获取能够避免多作一次排序操做。
覆盖索引其实更算一种思想,可以从辅助索引中获取信息,就不须要查询汇集索引中的数据。使用辅助索引的好处在于辅助索引包含的信息少,因此大小远小于汇集索引,所以能够大大减小IO 操做。
哈希索引是一种自适应的索引,数据库会根据表的使用状况自动生成哈希索引,咱们人为是没办法干预的。
InnoDB 储存引擎采用的哈希函数为除法散列方式,采用的冲突处理方法为链地址法。它指定查询的速度很快,可是范围查询就无能为力了。
全文索引用于实现关键词搜索。但它只能根据空格分词,所以不支持中文。
索引的优势:
索引的缺点
扩展
聚簇索引和非聚簇索引:
哪些状况须要加索引?
哪些状况不须要加索引?
什么是事务,它有哪些特性?
事务就是一组原子性的操做,这些操做要么所有发生,要么所有不发生。事务把数据库从一种一致性状态转换成另外一种一致性状态。
事务具备ACID 四种特性,即原子性(atomicity),一致性(consistency),隔离性(isolation),持久性(durability):
事务的隔离级别,分别解决了什么问题?
事务有4 个隔离级别,分别是:
隔离级别依次提升,分别解决了脏读、不可重读和幻读。
不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住知足条件的行,解决幻读须要锁表
事务是基于重作日志(redo log)文件和回滚日志(undo log)实现的
每提交一个事务必须先将该事务的全部日志写入到重作日志文件进行持久化,数据库就能够经过重作日志来保证事务的原子性和持久性。
每当有修改事务时, 还会产生undo log,若是须要回滚, 则根据undo log反向语句进行逻辑操做,好比insert一条记录就delete一条记录。undo log主要实现数据库的一致性, 还能够用来实现MVCC。
a.经过show status命令了解各SQL执行的频率
show [session|global] status like “Com_%”;
常见的执行参数
1 mysql> show global status like " 2 Slow_queries"; 3 +---------------+-------+ 4 | Variable_name | Value | 5 +---------------+-------+ 6 | Slow_queries | 0 | 7 +---------------+-------+ 8 1 row in set
b. 定位执行效率最低的sql语句
能够经过两个办法定位效率较低的SQL 语句:
c.经过EXPLAIN 分析低效SQL 的执行计划
查询到效率低的sql 语句后,能够经过EXPLAIN 分析低效SQL 的执行计划。
mysql> explain select * from comment ; +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+ | 1 | SIMPLE | comment | NULL | ALL | NULL | NULL | NULL | NULL | 92 | 100 | NULL | +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+ 1 row in set mysql>
d.经过show profile 分析SQL
//默认不开启profile,使用时先开启profile mysql> set profiling=1; Query OK, 0 rows affected mysql> select @@profiling; +-------------+ | @@profiling | +-------------+ | 1 | +-------------+ 1 row in set //在InnoDB 下获取表行数 mysql> select count(*) from comment; +----------+ | count(*) | +----------+ | 92 | +----------+ 1 row in set // 查开执行时间 mysql> show profiles; +----------+------------+------------------------------+ | Query_ID | Duration | Query | +----------+------------+------------------------------+ | 1 | 0.0109785 | select @@profiling | | 2 | 0.05502275 | select count(*) from comment | +----------+------------+------------------------------+ 2 rows in set //具体查开每一步执行时间 mysql> show profile for query 2 ; +----------------------+----------+ | Status | Duration | +----------------------+----------+ | starting | 9.2E-5 | | checking permissions | 9E-6 | | Opening tables | 2E-5 | | init | 1.8E-5 | | System lock | 9E-6 | | optimizing | 0.054635 | //在优化处理耗时最多 | statistics | 5.6E-5 | | preparing | 1.7E-5 | | executing | 5E-6 | | Sending data | 8E-5 | | end | 5E-6 | | query end | 1.5E-5 | | closing tables | 9E-6 | | freeing items | 3.6E-5 | | cleaning up | 1.9E-5 | +----------------------+----------+ 15 rows in set mysql>
f. 还能够经过trace 分析优化器如何选择执行计划的(有兴趣能够看一下)
a.对大批量插入数据
能够经过DISABLE KEY 和 ENABLE KEY 关闭和打开MYISAM 表索引的更新来提升效率。
1 ALTER TABLE table_name DISABLE KEY //在导入数据前关闭索引更新 2 loading the data 3 ALTER TABLE table_name ENABLE KEY //导入完成后开启
b.优化INSERT 语句
insert into table_name values(1,2)(1,3)(1,4)...
c 优化order by 语句
d. 优化group by 语句
默认状况下group by 语句对分组的数据进行排序操做,若是不须要排序操做能够经过order by null 禁止排序。
e. 优化嵌套语句
若是能够的话,特别是where 中包含索引的状况,用join 语法来代替嵌套语法(in)由于join 不须要在MySQL 的内存中建立临时表。
f. 优化or语句
对于含有or 的查询语句,若是要利用索引,则or 之间的每个条件都必须用到索引,若是没用索引,能够考虑增长索引。不然会全表扫面。
g. 优化分页查询
通常分页查询时,经过建立覆盖索引可以比较好的提升性能。一个常见又头痛的场景是"limit 1000,20" 此时MySQL 排序出前1020 条数据后,只须要返回20条数据,查询和排序的代价都很高。有两种优化方案
1 mysql> explain select comment_id,comment_content from comment order by comment_create_time limit 50,5; 2 +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+ 3 | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | 4 +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+ 5 | 1 | SIMPLE | comment | NULL | ALL | NULL | NULL | NULL | NULL | 92 | 100 | Using filesort | 6 +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+ 7 1 row in set 8 9 mysql> explain select a.comment_id,a.comment_content from comment a inner join(select comment_id from comment order by comment_create_time limit 50,5)b on a.comment_id=b.comment_id ; 10 +----+-------------+------------+------------+--------+---------------+---------+---------+--------------+------+----------+----------------+ 11 | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | 12 +----+-------------+------------+------------+--------+---------------+---------+---------+--------------+------+----------+----------------+ 13 | 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 55 | 100 | NULL | 14 | 1 | PRIMARY | a | NULL | eq_ref | PRIMARY | PRIMARY | 4 | b.comment_id | 1 | 100 | NULL | 15 | 2 | DERIVED | comment | NULL | ALL | NULL | NULL | NULL | NULL | 92 | 100 | Using filesort | 16 +----+-------------+------------+------------+--------+---------------+---------+---------+--------------+------+----------+----------------+ 17 3 rows in set
h. 使用SQL 提示
SQL 提示是优化数据库的一个重要手段,经常使用的SQL 提示:
推荐数据库使用某个索引,可让Mysql 再也不考虑其余可用索引
1 sql语句 use index(index_name);
忽视数据库某个索引,可让Mysql 再也不考虑这个索引
1 sql语句 ignore index(index_name);
强迫数据库使用某个索引,使用use index 数据库仍是可能不用这个索引,可是force index 数据库必须使用这个索引
1 sql语句 force index(index_name);
第一范式:
确保每列的原子性(强调的是列的原子性,即列不可以再分红其余几列).若是每列(或者每一个属性)都是不可再分的最小数据单元(也称为最小的原子单元),则知足第一范式.
例如:顾客表(姓名、编号、地址、……)其中"地址"列还能够细分为国家、省、市、区等。
第二范式:
在第一范式的基础上更进一层,目标是确保表中的每列都和主键相关(一是表必须有一个主键;二是没有包含在主键中的列必须彻底依赖于主键,而不能只依赖于主键的部分)若是一个关系知足第一范式,而且除了主键之外的其它列,都依赖于该主键,则知足第二范式.
例如:订单表(订单编号、产品编号、定购日期、价格、……),"订单编号"为主键,"产品编号"和主键列没有直接的关系,即"产品编号"列不依赖于主键列,应删除该列。
第三范式:
在第二范式的基础上更进一层,目标是确保每列都和主键列直接相关,而不是间接相关(另外非主键列必须直接依赖于主键,不能存在传递依赖).若是一个关系知足第二范式,而且不依赖于除了主键之外的其它列,则知足第三范式.
为了理解第三范式,须要根据Armstrong千米之必定义传递依赖。假设A、B和C是关系R的三个属性,若是A-〉B且B-〉C,则从这些函数依赖中,能够得出A-〉C,如上所述,
依赖A-〉C是传递依赖。
例如:订单表(订单编号,定购日期,顾客编号,顾客姓名,……),初看该表没有问题,知足第二范式,每列都和主键列"订单编号"相关,再细看你会发现"顾客姓名"和"顾客
编号"相关,"顾客编号"和"订单编号"又相关,最后通过传递依赖,"顾客姓名"也和"订单编号"相关。为了知足第三范式,应去掉"顾客姓名"列,放入客户表中。
存储过程是一些预编译的SQL语句。
优势:
缺点:
视图是一种虚拟的表,具备和物理表相同的功能,没有物理存储。能够对视图进行增,改,查,操做,试图一般是有一个表或者多个表的行或列的子集。对视图的修改不影响基本表。它使得咱们获取数据更容易,相比多表查询。
使用场景:
超键:在关系中能惟一标识元组的属性集称为关系模式的超键。一个属性能够为做为一个超键,多个属性组合在一块儿也能够做为一个超键。超键包含候选键和主键。
候选键:是最小超键,即没有冗余元素的超键。
主键:数据库表中对储存数据对象予以惟一和完整标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null)。
外键:在一个表中存在的另外一个表的主键称此表的外键
组合两个表中的记录,返回关联字段相符的记录,也就是返回两个表的交集(阴影)部分。
left join 是left outer join的简写,它的全称是左外链接,是外链接中的一种。
左(外)链接,左表(a_table)的记录将会所有表示出来,而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。
right join是right outer join的简写,它的全称是右外链接,是外链接中的一种。
与左(外)链接相反,右(外)链接,左表(a_table)只会显示符合搜索条件的记录,而右表(b_table)的记录将会所有表示出来。左表记录不足的地方均为NULL。
MySQL目前不支持此种方式,能够用其余方式替代解决。
完整性约束是对字段进行限制,从而符合该字段达到咱们指望的效果好比字段含有默认值,不能是NULL等, 主要有惟1、自增、主键、外键约束
1 PRIMARY KEY (PK) 标识该字段为该表的主键,能够惟一的标识记录 2 FOREIGN KEY (FK) 标识该字段为该表的外键 3 NOT NULL 标识该字段不能为空 4 UNIQUE KEY (UK) 标识该字段的值是惟一的 5 AUTO_INCREMENT 标识该字段的值自动增加(整数类型,并且为主键) 6 DEFAULT 为该字段设置默认值 7 8 UNSIGNED 无符号 9 ZEROFILL 使用0填充
参考文章:https://blog.csdn.net/qq_36906627/java/article/details/86634518