From ab2238b7627ae1ba021cca75d4ed0bc44ba19467 Mon Sep 17 00:00:00 2001 From: Zhang Peng Date: Sun, 8 Jul 2018 00:23:15 +0800 Subject: [PATCH] :memo: Writing docs. --- docs/数据库系统概论.md | 69 +++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/docs/数据库系统概论.md b/docs/数据库系统概论.md index be4f5af..8e695a0 100644 --- a/docs/数据库系统概论.md +++ b/docs/数据库系统概论.md @@ -63,11 +63,9 @@ tags: 优点: -- 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 -- 大大减少了服务器需要扫描的数据行数,从而提高检索速度。 -- 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 -- 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 -- 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 +- 索引大大减少了服务器需要扫描的数据量。 +- 索引可以帮助服务器避免排序和临时表。 +- 索引可以将随机 I/O 变为顺序 I/O。 缺点: @@ -141,6 +139,57 @@ B+Tree 是 B-Tree 的变种: ### 1.4. 索引原则 +#### 独立的列 + +如果查询中的列不是独立的列,则数据库不会使用索引。 + +“独立的列” 是指索引列不能是表达式的一部分,也不能是函数的参数。 + +:x: 错误示例: + +```sql +SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5; +SELECT ... WHERE TO_DAYS(CURRENT_DAT) - TO_DAYS(date_col) <= 10; +``` + +#### 前缀索引和索引选择性 + +有时候需要索引很长的字符列,这会让索引变得大且慢。 + +解决方法是:可以索引开始的部分字符,这样可以大大节约索引空间,从而提高索引效率。但这样也会降低索引的选择性。 + +索引的选择性是指:不重复的索引值和数据表记录总数的比值。最大值为 1,此时每个记录都有唯一的索引与其对应。选择性越高,查询效率也越高。 + +对于 BLOB/TEXT/VARCHAR 这种文本类型的列,必须使用前缀索引,因为数据库往往不允许索引这些列的完整长度。 + +要选择足够长的前缀以保证较高的选择性,同时又不能太长(节约空间)。 + +#### 多列索引 + +为每个列创建独立的索引往往不如多列索引。 + +经验法则:将选择性高的列或基数大的列优先排在多列索引最前列。但有时,也需要考虑 WHERE 子句中的排序、分组和范围条件等因素,这些因素也会对查询性能造成较大影响。 + +#### 聚簇索引 + +聚簇索引不是一种单独的索引类型,而是一种数据存储方式。 + +聚簇表示数据行和相邻的键值紧凑地存储在一起。因为无法同时把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。 + +#### 覆盖索引 + +索引包含所有需要查询的字段的值。 + +具有以下优点: + +- 因为索引条目通常远小于数据行的大小,所以若只读取索引,能大大减少数据访问量。 +- 一些存储引擎(例如 MyISAM)在内存中只缓存索引,而数据依赖于操作系统来缓存。因此,只访问索引可以不使用系统调用(通常比较费时)。 +- 对于 InnoDB 引擎,若辅助索引能够覆盖查询,则无需访问主索引。 + +#### 使用索引扫描来做排序 + +索引最好既满足排序,又用于查找行。这样,就可以使用索引来对结果排序。 + #### 最左前缀匹配原则 mysql 会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。 @@ -151,22 +200,12 @@ mysql 会一直向右匹配直到遇到范围查询(>、<、between、like)就 比如 a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql 的查询优化器会帮你优化成索引可以识别的形式。 -#### 尽量选择区分度高的列作为索引 - -让选择性最强的索引列放在前面,索引的选择性是指:不重复的索引值和记录总数的比值。最大值为 1,此时每个记录都有唯一的索引与其对应。选择性越高,查询效率也越高。 - -示字段不重复比例公式: `count(distinct col) / count(*)` - #### 索引列不能参与计算 在进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引。 例如下面的查询不能使用 actor_id 列的索引: -```sql -SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5; -``` - #### 尽量的扩展索引,不要新建索引 比如表中已经有 a 的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。