赞
踩
索引(在MySQL
中也称为"键")是存储引擎用于快速查找记录的一种数据结构,是数据库中的重要组成部分。索引的基本功能是帮助数据库快速定位和访问数据,从而提高查询性能。
索引在数据库中起到类似于书的目录的作用。当我们想要在一本书中找到特定的主题时,我们会先查阅目录,找到对应的页码,然后直接翻到该页码即可查看相关内容。在MySQL
中,存储引擎使用类似的方式利用索引来加速查询:
索引的优化是查询性能优化中最有效的手段之一。在数据量较大且负载较高的情况下,良好的索引设计可以将查询性能提高几个数量级。相反,不恰当的索引设计会导致性能下降。
MySQL
中索引的类型索引的本质是通过缩小需要筛选的数据范围,从而加快查询速度。它将随机访问转换为顺序访问,类似于在书中先查目录再找到对应的页码,从而提高查询效率。
通过索引机制,我们可以以一种固定的方式查询数据,而不需要逐个遍历所有数据。索引可以帮助数据库引擎快速定位和访问数据,从而加速查询过程。
索引的创建速度在表中存在大量数据时会变得较慢。创建索引需要对表中的数据进行排序和组织,这个过程可能会消耗较长的时间。
在索引创建完成后,对表的查询性能会显著提升,但写入性能会下降。因为每次对表进行插入、更新或删除操作时,都需要更新索引,这会增加额外的开销。
因此,不应该随意地创建索引。需要根据具体的业务需求和数据特点来判断是否需要创建索引,以避免不必要的性能损耗。
在考虑是否创建索引时,需要综合考虑以下几点:
当满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。索引可以加速查询过程,特别是在大数据量的情况下。
反之,如果某列不经常用于条件查询,或经常进行插入、修改操作,或磁盘空间有限,就不建议创建索引。创建过多的索引可能会增加存储空间和写入性能的开销,甚至导致索引失效,影响整体性能。因此,需要根据具体情况慎重考虑是否创建索引。
create index 索引名 on 表名(字段名);
# 索引名的命名规则一般是:index_表名_列名
show index from 表名;
drop index 索引名 on 表名;
B+树是一种平衡查找树的数据结构,被广泛应用于数据库系统和文件系统中的索引结构。它相比于其他树状结构(如二叉搜索树)具有更高的查询性能和更好的存储利用率。
B+树具有以下特点:
B+树的应用主要包括数据库系统和文件系统中的索引结构。在数据库系统中,B+树常被用作数据库表的索引结构,能够高效地支持查找、插入、删除等操作。在文件系统中,B+树常被用来维护文件的目录结构,可以快速定位和访问文件。
总之,B+树是一种高效的数据结构,具有平衡性、多路搜索、顺序访问性和存储利用率高等特点,适用于需要高效查询和排序的场景。它的查询次数由树的层级决定,层级越低查询次数越少。另外,B+树的叶子节点存放真实数据,而根和树枝节点存放的是虚拟数据(即关键字)。
MySQL
中,聚簇索引是基于B+树的数据结构实现的,它会把数据存储在索引的叶子节点上,叶子节点之间按顺序链接,使得按主键进行搜索时速度最快。ALTER TABLE table_name ADD PRIMARY KEY (column);
table_name
是表的名称,column
是要作为主键的列名。ALTER TABLE table_name ADD INDEX index_name (column);
table_name
是表的名称,index_name
是索引的名称,column
是要作为索引的列名。辅助索引适用于类似于搜索或排序等需要频繁进行的查询操作。
当查询涉及到的列不是聚集索引的键值时,辅助索引可以提供更高效的查询性能。
需要注意的是,在设计数据库时,应根据实际情况综合考虑聚集索引和辅助索引的选择。
聚集索引适用于经常以特定顺序扫描整个表或者频繁按照某个列进行范围查找的场景,而辅助索引则适用于单列或多列的等值或范围查找场景。
理想情况下,辅助索引应当能够满足大部分查询需求,从而避免全表扫描。
MySQL
中,可以通过以下语法创建唯一索引:ALTER TABLE table_name ADD UNIQUE KEY index_name (column);
table_name
是表的名称,index_name
是索引的名称,column
是要作为唯一索引的列名。与普通索引不同的是,如果尝试向包含唯一索引的列中插入重复的值,则会引发错误。唯一索引可以用于确保数据的一致性和完整性,并且可以帮助提高查询性能。
唯一索引常用于需要保证某列的值唯一性的情况,例如在用户表中,可以将用户名列设置为唯一索引,以确保每个用户名都是唯一的。这样可以避免重复的用户名被插入,同时在查询用户时也可以通过唯一索引快速定位到对应的用户记录。
需要注意的是,唯一索引并不限制该列的值为非空,如果需要同时限制唯一性和非空性,可以使用主键索引或在列上添加非空约束。
MySQL
中,可以通过以下语法创建组合索引:ALTER TABLE table_name ADD INDEX index_name (column1, column2, ...);
MySQL
会首先使用最左的列进行匹配,然后逐步向右扩展。虽然组合索引可以提高查询性能,但也存在一些缺点。例如,如果添加了不需要的列或删除了不需要的列,可能会导致组合索引变得无效。此外,如果创建了太多的组合索引,也可能会增加索引维护的成本。因此,在创建组合索引时需要谨慎考虑。
组合索引适用于需要同时查询多个列的情况。例如,在一个订单表中,经常需要按照订单日期和客户ID进行查询,可以创建一个组合索引来加快这类查询的速度。组合索引可以将多个列的值组合在一起进行索引,从而减少磁盘I/O操作,提高查询效率。
需要注意的是,组合索引并不是越多越好,过多的组合索引可能会增加索引的维护成本,并且在更新数据时可能会导致性能下降。因此,在设计数据库时,应根据实际情况选择合适的组合索引。
MySQL
中,可以通过以下语法创建全文索引:CREATE FULLTEXT INDEX index_name ON table_name (column);
index_name
是索引的名称,table_name
是表的名称,column
是要创建全文索引的列名。需要注意的是,只有MyISAM
和InnoDB
存储引擎支持全文索引。其他存储引擎如MEMORY
、CSV
等不支持全文索引。
创建全文索引可能会增加索引维护的成本,并且可能会降低其他类型的查询性能。因此,在创建全文索引时需要权衡其利弊。全文索引适用于需要对文本内容进行搜索和匹配的场景,例如在文章、博客、论坛等应用中搜索关键词。
全文索引可以提供更高效的文本搜索功能,支持模糊匹配、近似匹配和排序等操作。它可以帮助用户快速找到包含特定关键词的文本内容,提高查询的效率和准确性。
需要注意的是,全文索引的创建和使用需要一定的额外配置和注意事项,例如需要设置最小词长度、停用词列表等。在使用全文索引时,可以根据具体需求进行调整和优化,以获得更好的搜索性能和结果。
MySQL
中,可以通过以下语法创建前缀索引:ALTER TABLE table_name ADD INDEX index_name (column(length));
table_name
是表的名称,index_name
是索引的名称,column
是要创建前缀索引的列名,length
参数表示要保留的字符数。ALTER TABLE table_name ADD INDEX idx_postcode(postcode(2));
在这个例子中,索引只会包含邮政编码的最后两位数字。当执行范围查询时,MySQL
可以直接使用前缀索引来缩小搜索范围,从而提高查询性能。
需要注意的是,使用前缀索引可能会导致一些查询结果的不准确性,因为索引只存储了部分值。因此,在创建前缀索引时需要权衡索引大小和查询准确性之间的关系,并根据具体情况选择合适的前缀长度。
本质上说是不可重复读的一种现象
幻读并不是指两次读取获取的结果集不同,而是指某一次的查询操作得到的结果无法支撑后续的业务操作。
例如,当判断某条记录不存在并准备插入该记录时,却发现该记录已经存在,导致无法插入,这就是幻读。
MVCC
(多版本并发控制)机制Atomicity
):事务是一个不可再分割的单位,要么全部执行成功,要么全部回滚到初始状态,没有中间状态。Consistency
):事务执行前后,数据库的状态必须保持一致。Isolation
):多个事务可能同时执行,事务之间应该相互隔离,互不影响。Durability
):一旦事务提交,对数据库的更改应该是永久性的,即使在系统故障的情况下也不应该丢失。Read uncommitted
):
Read committed
):
Repeatable read
):
Serializable
):、
MySQL
的存储引擎默认的隔离级别InnoDB
默认的隔离级别是可重复读。MySQL
幻读的解决办法Next-key lock
的行级锁来解决幻读问题。MVCC
机制MVCC
机制MVCC
,全称为Multi-Version Concurrency Control
,即多版本并发控制协议。MySQL
的InnoDB
存储引擎实现的一种并发控制协议。MVCC
的优势MVCC
的主要优势在于它实现了读不加锁,避免了读写冲突,从而提高了系统的并发性能。MVCC
也解决了数据的脏读问题,保证了数据的一致性。MVCC
的读操作在MVCC
的并发控制系统中,读操作可以分为两类:快照读和当前读。
快照读:
当前读:
在并发环境中,多个事务可能会同时操作同一份数据,如果没有适当的控制,就可能会导致数据的不一致性。
例如,两个事务同时读取同一份数据,然后基于读取的数据进行修改,最后写回数据库,这就可能导致数据的不一致性。
锁机制可以确保在任何时刻,只有一个事务能够操作被锁定的数据。
这样,即使有多个并发的事务,也能保证数据的一致性和完整性。
虽然锁机制可能会降低系统的并发性能,但是它能够提高数据的安全性,防止数据的不一致性,这是在数据库系统中非常重要的。
数据库的锁可以按照粒度分为行级锁、表级锁和页级锁。
行级锁:
表级锁:
页级锁:
开销大,加锁慢:
会出现死锁:
锁定粒度最小,发生锁冲突的概率最低,并发度也最高:
InnoDB
会锁定这条主键索引对应的行。InnoDB
会先锁定这条辅助索引,然后再锁定相关的主键索引。这是因为在InnoDB
中,辅助索引的叶子节点存储的是主键值,所以在通过辅助索引查找数据时,需要先找到辅助索引,然后通过辅助索引找到主键值,最后通过主键值找到数据。InnoDB
会锁定整张表。虽然本质上还是行锁,但是因为锁定的是所有行,所以效果等同于表锁。Record lock
(记录锁)、Gap lock
(间隙锁)和Next-key lock
(下一个键锁)。Next-key lock
是MySQL
默认的锁机制,它是Record lock
和Gap lock
的结合,可以解决幻读问题。事务1(终端1) | 事务2(终端2) |
---|---|
start transaction; | start transaction; |
select * from user_id where id=6 for update; | delete from user_id where id=3; |
update user_id set age=18 where id=3; | delete from user_id where id=6; – 阻塞 |
SQL
语句,分别持有了一把锁,然后又尝试获取另一把锁,导致死锁的发生。InnoDB
存储引擎会检测到并抛出异常来处理死锁问题。然而,有一种死锁问题非常隐蔽。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。