📝 Writing docs.

pull/1/head
Zhang Peng 2018-07-08 00:23:15 +08:00
parent c4f43f64b9
commit ab2238b762
1 changed files with 54 additions and 15 deletions

View File

@ -63,11 +63,9 @@ tags:
优点: 优点:
- 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 - 索引大大减少了服务器需要扫描的数据量。
- 大大减少了服务器需要扫描的数据行数,从而提高检索速度。 - 索引可以帮助服务器避免排序和临时表。
- 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 - 索引可以将随机 I/O 变为顺序 I/O。
- 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
- 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
缺点: 缺点:
@ -141,6 +139,57 @@ B+Tree 是 B-Tree 的变种:
### 1.4. 索引原则 ### 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)就停止匹配。 mysql 会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。
@ -151,22 +200,12 @@ mysql 会一直向右匹配直到遇到范围查询(>、<、between、like)就
比如 a = 1 and b = 2 and c = 3 建立a,b,c索引可以任意顺序mysql 的查询优化器会帮你优化成索引可以识别的形式。 比如 a = 1 and b = 2 and c = 3 建立a,b,c索引可以任意顺序mysql 的查询优化器会帮你优化成索引可以识别的形式。
#### 尽量选择区分度高的列作为索引
让选择性最强的索引列放在前面,索引的选择性是指:不重复的索引值和记录总数的比值。最大值为 1此时每个记录都有唯一的索引与其对应。选择性越高查询效率也越高。
示字段不重复比例公式: `count(distinct col) / count(*)`
#### 索引列不能参与计算 #### 索引列不能参与计算
在进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引。 在进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引。
例如下面的查询不能使用 actor_id 列的索引: 例如下面的查询不能使用 actor_id 列的索引:
```sql
SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5;
```
#### 尽量的扩展索引,不要新建索引 #### 尽量的扩展索引,不要新建索引
比如表中已经有 a 的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。 比如表中已经有 a 的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。