索引用的什么数据结构,为什么选B+不用B 为什么不用跳表
B+树非叶子结点不会存储所有数据,层数相对较低
B+树叶子节点有双向链表结构,可以遍历
b+树是在平衡树的基础上做了矮胖化处理,降低了树高,将一部分随机io转化为顺序io,扫的数据很多,时间复杂度其实是变大了,但是因为磁盘顺序io比随机io快太多了,所以可以牺牲一点时间复杂度来提高性能,但是redis都是在内存里面,不存在随机io和顺序io的区别,也就只需要考虑时空复杂度,用跳表肯定更好,同时跳表的实现相对来说简单一点
什么情况下索引失效
最佳左前缀法则 严禁左模糊或者全模糊 %*%
搜索列 带了表达式
类型转换导致索引失效 123 ‘123’
设置索引时需要注意的问题
-
只为搜索、排序或分组的列建索引
-
考虑索引列中不重复值的个数
-
索引列的类型尽量小
-
为列前缀建立索引 ( ALTER TABLE single_table ADD INDEX idx_key1(key10) )
-
覆盖索引 查询列表只包含索引列
-
让索引列以列名的形式在搜索条件中单独出现
-
新插入记录时主键大小对效率的影响
-
冗余和重复索引
查询优化器的工作方式
条件化简
-
移除不必要的括号
-
常量传递
-
移除没用的条件
-
表达式计算
-
子查询优化
MYSQL有哪些锁
表级别的S锁,X锁: LOCK TABLES t READ LOCK TABLES t WRITE
ALTER TABLE ,DROP TABLE 执行select 元数据锁(MDL)
表级别的IS锁,IX锁
表级别的AUTO-INC锁 插入语句的时候加一个表级别的AUTO-INC锁
行级锁
Record Lock
Gap Lock Next-key Lock
Insert Intention Lock
隐式锁:
select ... lock in share mode;
select ... for update
update ...
delete ...
如何查看SQL执行:explain explain包含什么
包含 id 表名 可能使用的索引 针对单表的访问方法 实际使用的索引 ref const range 实际使用的索引的长度 读取的记录条数 经过条件过滤后剩余记录条数的百分比 额外的信息
sql执行流程
mysql客户端与服务器通讯
查询缓存(大小写敏感的哈希查找)
查询优化
查询执行引擎
返回给客户端
8.聚簇索引和非聚簇索引,回表
建表的时候 指定 (key | index)索引名 列
ALTER TABLE 表名 ADD (KEY| INDEX) 索引名 列
ALTER TABLE 表名 DROP (KEY| INDEX) 索引名
聚簇索引 是根据主键默认的索引 mysql innodb 数据及索引 索引即数据
二级索引 自己根据业务来建的索引,除了聚簇索引,其他的都是二级索引,二级索引的叶子节点包含索引列和主键
查询语句 根据自己建立的索引,查询时,先会从二级索引查询到相应的数据,然后根据主键去聚簇索引查询完整数据,称为回表
数据库事务ACID,mysql默认隔离级别
需要保证acid的一个或多个数据库操作称为事务
a 原子性
c 一致性
i 隔离性
d 持久性
脏写,一个事务修改了另一个未提交事务修改了的数据
脏读 一个事务读了另一个未提交的事务修改的数据
不可重复读 一个事务修改了另一个未提交的事务读取的数据
幻读 一个事务根据条件P 读取了数据,还未提交,另一个事物增删改这个条件的数据 之前的事务又读取了P条件的数据
ru 读未提交
rc 读已提交 解决了脏读
rr 可重复读(默认) 解决了脏读 不可重复读
可序列化 解决了脏读 不可重复读 幻读
4.如何设置隔离级别,即隔离级别的命令?
SET [GLOBAL | SESSION ] TRANSACTION ISOLAYION LEVEL level;
22.Mysql引擎有哪些(只说了innodb和myisam)
innodb myisam memory
## MySQL的LIMIT
### server层和存储引擎层
* server层负责处理一些通用的事情,诸如连接管理、SQL语法解析、分析执行计划之类的东西
* 存储引擎层负责具体的数据存储,诸如数据是存储到文件上还是内存里,具体的存储格式是什 么样的之类的。我们现在基本都使用InnoDB存储引擎,其他存储引擎使用的非常少了,所以我们也就不涉及其他存储引擎了。
**MySQL是在server层准备向客户端发送记录的时候才会去处理LIMIT子句中的内容。** 先在二级索引去找,再回表得到完整记录,返回给server层,server层发现limit 要求 他会做一个统计是第几条,存储引擎不断在二级索引向下找,并且回表,再将完整数据返回给server层,成本太大,不如全表扫描+filesort快
SELECT * FROM t, (SELECT id FROM t ORDER BY key1 LIMIT 5000, 1) AS d
WHERE t.id = d.id;
这样, `SELECT id FROM t ORDER BY key1 LIMIT 5000, 1`作为一个子查询单独存在,由于该子查询的查询列表只有一个 `id` 列,MySQL可以通过仅扫描二级索引`idx_key1`执行该子查询,然后再根据子查询中获得到的主键值去表t中进行查找。 就可以省掉回表的成本