时间:2021-07-01 10:21:17 帮助过:7人阅读
InnoDB:
MySIAM:
操作区别:
选择:
索引是对数据库表中一或多个列的值进行排序的结构,是帮助MySQL高效获取数据的数据结构
(数据库是磁盘文件,磁盘IO 的代价较高,所以采用索引减少IO 次数)
Mysql 中常用的索引有B+ 树索引(包括普通索引、唯一索引、主键索引),哈希索引,全文索引,R-TREE 索引(空间索引,主要用于地理空间数据类型,很少使用)。
Mysql 传统意义上的索引为B+ 树索引,B+ 树索引的本质就是B+ 树在数据库中的实现,由于B+ 树的高扇出性,数据库中的B+ 树的高一般为2-4层,因此查找某一键值的行记录只需2-4次IO,大概0.02~0.04秒。
(扇出性:是指该模块直接调用的下级模块的个数。扇出大表示模块的复杂度高,需要控制和协调过多的下级模块)
B+ 树索引
主要分为聚集索引和辅助索引。
聚集索引是根据每张表的主键建造的一棵B+ 树,叶子节点中存放的是整张表的行记录。一张表只能有一个聚集索引。因为聚集索引在逻辑上是连续的,所以它对于主键的排序查找和范围查找速度非常快。
辅助索引与聚集索引不同的地方在于,辅助索引不是唯一的,它的叶子节点只包含行记录的部分数据以及对应聚集索引的节点位置。通过辅助索引来查找数据时,先遍历辅助索引找到对应主键索引,再通过主键索引查找对应记录。
在MYISAM 中主键索引和辅助索引都相当上述辅助索引,索引页中存放的是主键和指向数据页的偏移量,数据页中存放的是主键和该主键所属行记录的地址空间。唯一的区别是MYISAM 中主键索引不能重复,辅助索引可以。
从使用上来说还有联合索引和覆盖索引。
聚集索引是根据每张表的主键建造的一棵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 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
mysql面试常考知识点
标签:t_sql 增加 过多 原子性 方式 范式 分割 plain 表之间