数据库知识点

https://blog.csdn.net/ThinkWon/article/details/104778621?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162241626716780265459799%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=162241626716780265459799&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-104778621.first_rank_v2_pc_rank_v29&utm_term=mysql%E9%9D%A2%E8%AF%95%E9%A2%98&spm=1018.2226.3001.4187什么是SQL?结构化查询语言(Structured Query Language)简称SQL,是一种数据库查询语言。
作用:用于存取数据、查询、更新和管理关系数据库系统。

数据库三大范式
第一范式(确保每列保持原子性):如地址可以分成省份城市
第二范式(确保表中的每列都和主键相关): 订单号和商品编号要分成两个表
第三范式(确保每列都和主键列直接相关,而不是间接相关):如客户的信息与订单编号不相关

数据库的结构

数据库引擎层:有常见的MyISAM,InnoDB等等

SQL语言的执行过程(跟上图是一致的)

  1. 客户端首先通过连接器进行身份认证和权限相关
  2. 如果是执行查询语句的时候,会先查询缓存,但MySQL 8.0 版本后该步骤移除。
  3. 没有命中缓存的话,SQL 语句就会经过解析器,分析语句,包括语法检查等等。
  4. 通过优化器,将用户的SQL语句按照 MySQL 认为最优的方案去执行。
  5. 执行语句,并从存储引擎返回数据。
    MySQL的共享锁排它锁
    共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
    排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
    select是不加任何锁的故即使是有排它锁也能查询
    MySQL中的按粒度的锁分类
    表级锁: 对当前操作的整张表加锁,实现简单,加锁快,但并发能力低。
    行锁: 锁住某一行,如果表存在索引,那么记录锁是锁在索引上的,如果表没有索引,那么 InnoDB 会 创建一个隐藏的聚簇索引加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但 加锁的开销也最大,加锁慢,会出现死锁。
    页锁:处于行锁和表锁之间。
    如何解决数据库死锁
  6. 预先检测到死锁的循环依赖,并立即返回一个错误。
  7. 当查询的时间达到锁等待超时的设定后放弃锁请求。
    产生死锁的原因主要是:
    (1)系统资源不足。
    (2) 进程运行推进的顺序不合适。
    (3)资源分配不当等。
    下列方法有助于最大限度地降低死锁:
    (1)按同一顺序访问对象。
    (2)避免事务中的用户交互。
    (3)保持事务简短并在一个批处理中。
    (4)使用低隔离级别。
    (5)使用绑定连接。
    产生死锁的四个必要条件:
    (1) 互斥条件:一个资源每次只能被一个进程使用。
    (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
    (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
    (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
    这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
    死锁的预防和解除:
    理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源,在系统运行过程中,对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源,若分配后系统可能发生死锁,则不予分配,否则予以分配 。因此,对资源的分配要给予合理的规划。
    乐观锁和悲观锁
    乐观锁(加版本号):对于数据冲突保持一种乐观态度,操作数据时不会对操作的数据进行加锁,只有到数据提交的 时候才通过一种机制来验证数据是否存在冲突。 悲观锁(共享锁、排他锁):对于数据冲突保持一种悲观态度,在修改数据之前把数据锁住,然后再对数据进行读写,在它 释放锁之前任何人都不能对其数据进行操作,直到前面一个人把锁释放后下一个人数据加锁才可对数据 进行加锁,然后才可以对数据进行操作,一般数据库本身锁的机制都是基于悲观锁的机制实现的。
    InnoDB存储引擎
    简述InnoDB存储引擎 InnoDB 是 MySQL 的默认事务型引擎,支持事务,表是基于聚簇索引建立的。支持表级锁和行级锁, 支持外键,适合数据增删改查都频繁的情况。 InnoDB 采用 MVCC 来支持高并发,并且实现了四个标准的隔离级别。其默认级别是 REPEATABLE READ,并通过间隙锁策略防止幻读,间隙锁使 InnoDB 不仅仅锁定查询涉及的行,还会对索引中的间 隙进行锁定防止幻行的插入。
    简述MyISAM存储引擎
    MySQL5.1及之前,MyISAM 是默认存储引擎。MyISAM不支持事务,Myisam支持表级锁,不支持行级 锁,表不支持外键,该存储引擎存有表的行数,count运算会更快。适合查询频繁,不适合对于增删改要求高的情况
    简述Memory存储引擎
    Memory存储引擎将所有数据都保存在内存,不需要磁盘 IO。支持哈希索引,因此查找速度极快。 Memory 表使用表级锁,因此并发写入的性能较低。
    索引
    索引用B+树实现:B+树的优势:
  8. 单个节点可以存储更多的数据,减少I/O的次数。
  9. 查找性能更稳定,因为都是要查找到叶子结点。
  10. 叶子结点形成了有序链表,便于查询。
    索引是存储引擎中用于快速找到记录的一种数据结构。在关系型数据库中,索引具体是一种对数据库中 一列或多列的值进行排序的存储结构。
    索引的好处?(查询快,删除和增加慢)
    1.通过创建索引,可以在查询的过程中,提高系统的性能;
    2.通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性;
    3.在使用分组和排序子句进行数据检索时,可以减少查询中分组和排序的时间;
    聚集索引:主键索引就是聚集索引,将所有主键建成B+树,故必须唯一
    非聚集索引:非聚集索引和聚集索引的区别在于, 通过聚集索引可以查到需要查找的数据, 而通过非聚集索引可以查到记录对应的主键值 , 再使用主键的值通过聚集索引查找到需要的数据
    Mysql常见索引类型
    数据结构角度:
    B-Tree索引
    哈希索引
    R-Tree索引
    全文索引
    物理存储角度:
    主键索引(聚簇索引):叶子节点存的是整行的数据
    非主键索引(二级索引):叶子节点存的主键的值
    简述B-Tree与B+树
    B-Tree 是一种自平衡的多叉树。每个节点都存储关键字值。其左子节点的关键字值小于该节点关键字 值,且右子节点的关键字值大于或等于该节点关键字值。
    B+树也是是一种自平衡的多叉树。其基本定义与B树相同,不同点在于数据只出现在叶子节点,所有叶 子节点增加了一个链指针,方便进行范围查询。 B+树中间节点不存放数据,所以同样大小的磁盘页上可以容纳更多节点元素,访问叶子节点上关联的数 据也具有更好的缓存命中率。并且数据顺序排列并且相连,所以便于区间查找和搜索。
    B树每一个节点都包含key和value,查询效率比B+树高。
    Hash索引
    哈希索引对于每一行数据计算一个哈希码,并将所有的哈希码存储在索引中,同时在哈希表中保存指向 每个数据行的指针。只有 Memory 引擎显式支持哈希索引。 Hash索引不支持范围查询,无法用于排序,也不支持部分索引列匹配查找。
    自适应Hash索引
    InnoDB对于频繁使用的某些索引值,会在内存中基于 B-Tree 索引之上再创键一个哈希索引,这也被称 为自适应Hash索引。
    聚集索引和稀疏索引
    聚集索引按每张表的主键构建一棵B+树,数据库中的每个搜索键值都有一个索引记录,每个数据页通过 双向链表连接。表数据访问更快,但表更新代价高。 稀疏索引不会为每个搜索关键字创建索引记录。搜索过程需要,我们首先按索引记录进行操作,并按顺 序搜索,直到找到所需的数据为止。
    辅助索引与回表查询
    辅助索引是非聚集索引,叶子节点不包含记录的全部数据,包含了一个书签用来告诉InnoDB哪里可以找 到与索引相对应的行数据。 通过辅助索引查询,先通过书签查到聚集索引,再根据聚集索引查对应的值,需要两次,也称为回表查询。
    联合索引和最左匹配原则
    联合索引是指对表上的多个列的关键词进行索引。 对于联合索引的查询,如果精确匹配联合索引的左边连续一列或者多列,则mysql会一直向右匹配直到 遇到范围查询(>,<,between,like)就停止匹配。Mysql会对第一个索引字段数据进行排序,在第一个字 段基础上,再对第二个字段排序。
    覆盖索引
    覆盖索引指一个索引包含或覆盖了所有需要查询的字段的值,不需要回表查询,即索引本身存了对应的值。
    为什么数据库不用红黑树用B+树
    红黑树的出度为 2,而 B Tree 的出度一般都非常大。红黑树的树高 h 很明显比 B Tree 大非常多,IO次 数很多,导致会比较慢,因此检索的次数也就更多。 B+Tree 相比于 B-Tree 更适合外存索引,拥有更大的出度,IO次数较少,检索效率会更高。(红黑树是自平衡二叉搜索树,但是不完全平衡,放弃了平衡性,得到了较高的创建树的效率)
    基于主键索引的查询和非主键索引的查询有什么区别?
    对于select * from 主键=XX,基于主键的普通查询仅查找主键这棵树,对于select * from 非主键=XX, 基于非主键的查询有可能存在回表过程(回到主键索引树搜索的过程称为回表),因为非主键索引叶子节点仅存主键值,无整行全部信息。
    非主键索引的查询一定会回表吗?
    不一定,当查询语句的要求字段全部命中索引,不用回表查询。如select 主键 from 非主键=XX,此时非 主键索引叶子节点即可拿到主键信息,不用回表。
    简述MySQL使用EXPLAIN 的关键字段
    explain关键字用于分析sql语句的执行情况,可以通过他进行sql语句的性能分析。
    1.表的读取顺序
    2.数据读取操作的操作类型
    3.哪些索引可以使用
    4.哪些索引被实际使用
    5.表之间的引用
    6.每张表有多少行被优化器查询
    简述MySQL优化流程
  11. 通过慢日志定位执行较慢的SQL语句
  12. 利用explain对这些关键字段进行分析
  13. 根据分析结果进行优化
    简述MySQL中的日志log
    redolog: 存储引擎级别的log(InnoDB有,MyISAM没有),该log关注于事务的恢复.在重启mysql服务 的时候,根据redo log进行重做,从而使事务有持久性。
    undo log:是存储引擎级别的log(InnoDB有,MyISAM没有)保证数据的原子性,该log保存了事务发 生之前的数据的一个版本,可以用于回滚,是MVCC的重要实现方法之一。
    bin log:数据库级别的log,关注恢复数据库的数据。
    简述事务
    事务内的语句要么全部执行成功,要么全部执行失败。

定义:数据库事务是构成单一逻辑工作单元的操作集合(转账的例子,转100,收100应是一个事务)
数据库中多个事务同时进行可能会出现什么问题?
丢失修改
脏读:当前事务可以查看到别的事务未提交的数据。
不可重读:在同一事务中,使用相同的查询语句,同一数据资源莫名改变了。
幻读:在同一事务中,使用相同的查询语句,莫名多出了一些之前不存在的数据,或莫名少了一些 原先存在的数据。
脏读:

幻读:

丢弃修改:

不可重复读:

SQL的事务隔离级别有哪些?

什么是MVCC?
MVCC为多版本并发控制,即同一条记录在系统中存在多个版本。其存在目的是在保证数据一致性的前 提下提供一种高并发的访问性能。对数据读写在不加读写锁的情况下实现互不干扰,从而实现数据库的隔离性,在事务隔离级别为读提交和可重复读中使到。

在InnoDB中,事务在开始前会向事务系统申请一个事务ID,该ID是按申请顺序严格递增的。每行数据具 有多个版本,每次事务更新数据都会生成新的数据版本,而不会直接覆盖旧的数据版本。数据的行结构 中包含多个信息字段。其中实现MVCC的主要涉及最近更改该行数据的事务ID(DB_TRX_ID)和可以 找到历史数据版本的指针(DB_ROLL_PTR)。InnoDB在每个事务开启瞬间会为其构造一个记录当前 已经开启但未提交的事务ID的视图数组。通过比较链表中的事务ID与该行数据的值与对应的 DB_TRX_ID,并通过DB_ROLL_PTR找到历史数据的值以及对应的DB_TRX_ID来决定当前版本的数据 是否应该被当前事务所见。最终实现在不加锁的情况下保证数据的一致性。
读提交和可重复读都基于MVCC实现,有什么区别?
在可重复读级别下,只会在事务开始前创建视图,事务中后续的查询共用一个视图。而读提交级别下每 个语句执行前都会创建新的视图。因此对于可重复读,查询只能看到事务创建前就已经提交的数据。而 对于读提交,查询能看到每个语句启动前已经提交的数据。
InnoDB如何保证事务的原子性、持久性和一致性?
利用undo log保障原子性。该log保存了事务发生之前的数据的一个版本,可以用于回滚,从而保证事务原子性。
利用redo log保证事务的持久性,该log关注于事务的恢复.在重启mysql服务的时候,根据redo log进行重做,从而使事务有持久性。
利用undo log+redo log保障一致性。事务中的执行需要redo log,如果执行失败,需要undo log 回滚。
MySQL是如何保证主备一致的?
MySQL通过binlog(二进制日志)实现主备一致。binlog记录了所有修改了数据库或可能修改数据库的 语句,而不会记录select、show这种不会修改数据库的语句。在备份的过程中,主库A会有一个专门的 线程将主库A的binlog发送给 备库B进行备份。
其中binlog有三种记录格式:

  1. statement:记录对数据库进行修改的语句本身,有可能会记录一些额外的相关信息。优点是binlog日 志量少,IO压力小,性能较高。缺点是由于记录的信息相对较少,在不同库执行时由于上下文的环 境不同可能导致主备不一致。
  2. row:记录对数据库做出修改的语句所影响到的数据行以及对这些行的修改。比如当修改涉及多行数 据,会把涉及的每行数据都记录到binlog。优点是能够完全的还原或者复制日志被记录时的操作。 缺点是日志量占用空间较大,IO压力大,性能消耗较大。 3. mixed:混合使用上述两种模式,一般的语句使用statment方式进行保存,如果遇到一些特殊的函 数,则使用row模式进行记录。MySQL自己会判断这条SQL语句是否可能引起主备不一致,如果有 可能,就用row格式, 否则就用statement格式。但是在生产环境中,一般会使用row模式。
    redo log与binlog的区别?
  3. redo log是InnoDB引擎特有的,只记录该引擎中表的修改记录。binlog是MySQL的Server层实现 的,会记录所有引擎对数据库的修改。
  4. redo log是物理日志,记录的是在具体某个数据页上做了什么修改;binlog是逻辑日志,记录的是这 个语句的原始逻辑。
  5. redo log是循环写的,空间固定会用完;binlog是可以追加写入的,binlog文件写到一定大小后会切 换到下一个,并不会覆盖以前的日志。
    crash-safe能力是什么?
    InnoDB通过redo log保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crashsafe。
    WAL技术是什么?
    WAL的全称是Write-Ahead Logging,它的关键点就是先写日志,再写磁盘。事务在提交写入磁盘前, 会先写到redo log里面去。如果直接写入磁盘涉及磁盘的随机I/O访问,涉及磁盘随机I/O访问是非常消耗 时间的一个过程,相比之下先写入redo log,后面再找合适的时机批量刷盘能提升性能。
    两阶段提交是什么?
    为了保证binlog和redo log两份日志的逻辑一致,最终保证恢复到主备数据库的数据是一致的,采用两阶段提交的机制。
  6. 执行器调用存储引擎接口,存储引擎将修改更新到内存中后,将修改操作记录redo log中,此时 redo log处于prepare状态。 2. 存储引擎告知执行器执行完毕,执行器生成这个操作对应的binlog,并把binlog写入磁盘。
  7. 执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log改成提交commit状态,更新完成。
    只靠binlog可以支持数据库崩溃恢复吗?(binlog只记录对数据行的操作,不记录对页面的修改)

简述MySQL主从复制
MySQL提供主从复制功能,可以方便的实现数据的多处自动备份,不仅能增加数据库的安全性,还能进 行读写分离,提升数据库负载性能。
主从复制流程:

  1. 在事务完成之前,主库在binlog上记录这些改变,完成binlog写入过程后,主库通知存储引擎提交事 物
  2. 从库将主库的binlog复制到对应的中继日志,即开辟一个I/O工作线程,I/O线程在主库上打开一个普 通的连接,然后开始binlog dump process,将这些事件写入中继日志。从主库的binlog中读取事 件,如果已经读到最新了,线程进入睡眠并等待ma主库产生新的事件。
    读写分离:即只在MySQL主库上写,只在MySQL从库上读,以减少数据库压力,提高性能
    mysql有关权限的表都有哪几个
    MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些权限表分别user,db,table_priv,columns_priv和host。下面分别介绍一下这些表的结构和内容:

user权限表:记录允许连接到服务器的用户帐号信息,里面的权限是全局级的。
db权限表:记录各个帐号在各个数据库上的操作权限。
table_priv权限表:记录数据表级的操作权限。
columns_priv权限表:记录数据列级的操作权限。
host权限表:配合db权限表对给定主机上数据库级操作权限作更细致的控制。这个权限表不受GRANT和REVOKE语句的影响。
数据类型
mysql有哪些数据类型
分类 类型名称 说明
整数类型 tinyInt 很小的整数(8位二进制)
smallint 小的整数(16位二进制)
mediumint 中等大小的整数(24位二进制)
int(integer) 普通大小的整数(32位二进制)
小数类型 float 单精度浮点数
double 双精度浮点数
decimal(m,d) 压缩严格的定点数
日期类型 year YYYY 1901~2155
time HH:MM:SS -838:59:59~838:59:59
date YYYY-MM-DD 1000-01-01~9999-12-3
datetime YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00~ 9999-12-31 23:59:59
timestamp YYYY-MM-DD HH:MM:SS 19700101 00:00:01 UTC~2038-01-19 03:14:07UTC
文本、二进制类型 CHAR(M) M为0~255之间的整数
VARCHAR(M) M为0~65535之间的整数
TINYBLOB 允许长度0~255字节
BLOB 允许长度0~65535字节
MEDIUMBLOB 允许长度0~167772150字节
LONGBLOB 允许长度0~4294967295字节
TINYTEXT 允许长度0~255字节
TEXT 允许长度0~65535字节
MEDIUMTEXT 允许长度0~167772150字节
LONGTEXT 允许长度0~4294967295字节
VARBINARY(M) 允许长度0~M个字节的变长字节字符串
BINARY(M) 允许长度0~M个字节的定长字节字符串
1、整数类型,包括TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,分别表示1字节、2字节、3字节、4字节、8字节整数。任何整数类型都可以加上UNSIGNED属性,表示数据是无符号的,即非负整数。
长度:整数类型可以被指定长度,例如:INT(11)表示长度为11的INT类型。长度在大多数场景是没有意义的,它不会限制值的合法范围,只会影响显示字符的个数,而且需要和UNSIGNED ZEROFILL属性配合使用才有意义。
例子,假定类型设定为INT(5),属性为UNSIGNED ZEROFILL,如果用户插入的数据为12的话,那么数据库实际存储数据为00012。

2、实数类型,包括FLOAT、DOUBLE、DECIMAL。
DECIMAL可以用于存储比BIGINT还大的整型,能存储精确的小数。
而FLOAT和DOUBLE是有取值范围的,并支持使用标准的浮点进行近似计算。
计算时FLOAT和DOUBLE相比DECIMAL效率更高一些,DECIMAL你可以理解成是用字符串进行处理。

3、字符串类型,包括VARCHAR、CHAR、TEXT、BLOB
VARCHAR用于存储可变长字符串,它比定长类型更节省空间。
VARCHAR使用额外1或2个字节存储字符串长度。列长度小于255字节时,使用1字节表示,否则使用2字节表示。
VARCHAR存储的内容超出设置的长度时,内容会被截断。
CHAR是定长的,根据定义的字符串长度分配足够的空间。
CHAR会根据需要使用空格进行填充方便比较。
CHAR适合存储很短的字符串,或者所有值都接近同一个长度。
CHAR存储的内容超出设置的长度时,内容同样会被截断。

使用策略:
对于经常变更的数据来说,CHAR比VARCHAR更好,因为CHAR不容易产生碎片。
对于非常短的列,CHAR比VARCHAR在存储空间上更有效率。
使用时要注意只分配需要的空间,更长的列排序时会消耗更多内存。
尽量避免使用TEXT/BLOB类型,查询时会使用临时表,导致严重的性能开销。

4、枚举类型(ENUM),把不重复的数据存储为一个预定义的集合。
有时可以使用ENUM代替常用的字符串类型。
ENUM存储非常紧凑,会把列表值压缩到一个或两个字节。
ENUM在内部存储时,其实存的是整数。
尽量避免使用数字作为ENUM枚举的常量,因为容易混乱。
排序是按照内部存储的整数

5、日期和时间类型,尽量使用timestamp,空间效率高于datetime,
用整数保存时间戳通常不方便处理。
如果需要存储微妙,可以使用bigint存储。
看到这里,这道真题是不是就比较容易回答了。

索引
什么是索引?
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。

索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。

更通俗的说,索引就相当于目录。为了方便查找书中的内容,通过对内容建立索引形成目录。索引是一个文件,它是要占据物理空间的。

索引有哪些优缺点?
索引的优点

可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
索引的缺点

时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;
空间方面:索引需要占物理空间。

创建索引的原则(重中之重)
索引虽好,但也不是无限制的使用,最好符合一下几个原则

1) 最左前缀匹配原则,组合索引非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

2)较频繁作为查询条件的字段才去创建索引

3)更新频繁字段不适合创建索引

4)若是不能有效区分数据的列不适合做索引列(如性别,男女未知,最多也就三种,区分度实在太低)

5)尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

6)定义有外键的数据列一定要建立索引。

7)对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。

8)对于定义为text、image和bit的数据类型的列不要建立索引。

什么是最左前缀原则?什么是最左匹配原则
顾名思义,就是最左优先,在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。
最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
hash索引进行等值查询更快(一般情况下),但是却无法进行范围查询。
数据库为什么使用B+树而不是B树
1.B树只适合随机检索,而B+树同时支持随机检索和顺序检索;
2.B+树空间利用率更高,可减少I/O次数,磁盘读写代价更低。一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗。B+树的内部结点并没有指向关键字具体信息的指针,只是作为索引使用,其内部结点比B树小,盘块能容纳的结点中关键字数量更多,一次性读入内存中可以查找的关键字也就越多,相对的,IO读写次数也就降低了。而IO读写次数是影响索引检索效率的最大因素;
3.B+树的查询效率更加稳定。B树搜索有可能会在非叶子结点结束,越靠近根节点的记录查找时间越短,只要找到关键字即可确定记录的存在,其性能等价于在关键字全集内做一次二分查找。而在B+树中,顺序检索比较明显,随机检索时,任何关键字的查找都必须走一条从根节点到叶节点的路,所有关键字的查找路径长度相同,导致每一个关键字的查询效率相当。
4.B-树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。B+树的叶子节点使用指针顺序连接在一起,只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作。
5.增删文件(节点)时,效率更高。因为B+树的叶子节点包含所有关键字,并以有序的链表结构存储,这样可很好提高增删效率。
数据库优化见链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值