美文网首页MySQL
数据库索引

数据库索引

作者: 汉寿周杰伦 | 来源:发表于2020-03-19 22:00 被阅读0次

    数据库索引

    索引就是为了提高查询性能而存在的, 如果在查询中索引没有提高性能, 只能说是用错了索引,或者讲是场合不同

    字段1 字段2 字段3
    Employee_Name Employee_Age Employee_Address
    SELECT * FROM Employee 
    WHERE Employee_Name = 'Jesus'
    

    不加索引 -> 全表扫描

    使用索引的全部意义就是通过缩小一张表中需要查询的记录/行的数目来加快搜索的速度

    一、索引概念:

    一个索引是存储的表中一个特定列的值数据结构(最常见的是B-Tree)。索引是在表的列上创建。所以,要记住的关键点是索引包含一个表中列的值,并且这些值存储在一个数据结构中。请记住记住这一点:索引是一种数据结构 。

    一个非常好的类比是把数据库索引看作是书的索引
    如果你有一本关于狗的书,你想要找关于‘黄金猎犬’的那部分。当你可以通过在书背的索引找到哪几页有关于‘黄金猎犬’信息的时候,你为什么要翻完正本书 - 这相当于数据库中的全表扫描。同样的,就像一本书的索引包含页码一样,数据库的索引包含了指针,指向你在SQL中想要查询的值所在的行。

    (1)B-Tree索引结构

    B-Tree 是最常用的用于索引的数据结构。

    1. 因为它们是时间复杂度低, 查找、删除、插入操作都可以可以在对数时间内完成。
    2. 另外一个重要原因存储在B-Tree中的数据是有序的。数据库管理系统(RDBMS)通常决定索引应该用哪些数据结构。但是,在某些情况下,你在创建索引时可以指定索引要使用的数据结构。

    (2)哈希表索引

    哈希表是另外一种你可能看到用作索引的数据结构,这些索引通常被称为哈希索引。
    使用哈希索引的原因是,在寻找值时哈希表效率极高。所以,如果使用哈希索引,对于比较字符串是否相等的查询能够极快的检索出的值。

    例如之前我们讨论过的这个查询(SELECT * FROM Employee WHERE Employee_Name = ‘Jesus’) 就可以受益于创建在Employee_Name 列上的哈希索引。

    哈系索引的工作方式是将列的值作为索引的键值(key),和键值相对应实际的值(value)是指向该表中相应行的指针。因为哈希表基本上可以看作是关联数组,一个典型的数据项就像“Jesus => 0x28939″,而0x28939是对内存中表中包含Jesus这一行的引用。在哈系索引的中查询一个像“Jesus”这样的值,并得到对应行的在内存中的引用,明显要比扫描全表获得值为“Jesus”的行的方式快很多。

    哈希索引的缺点

    哈希表是无顺的数据结构,对于很多类型的查询语句哈希索引都无能为力。

    举例来说,假如你想要找出所有小于40岁的员工。你怎么使用使用哈希索引进行查询?这不可行,因为哈希表只适合查询键值对,也就是说查询相等的查询(例:like “WHERE name = ‘Jesus’)。

    哈希表的键值映射也暗示其键的存储是无序的。这就是为什么哈希索引通常不是数据库索引的默认数据结构,因为在作为索引的数据结构时,其不像B-Tree那么灵活

    (3)其他类型的索引

    1. 使用R-Tree作为数据结构的索引通常用来为空间问题提供帮助。
      例如,一个查询要求“查询出所有距离我两公里之内的星巴克”,如果数据库表使用R- Tree索引,这类查询的效率将会提高。
    2. 另一种索引是位图索引(bitmap index), 这类索引适合放在包含布尔值(true 和 false)的列上,但是这些值(表示true或false的值)的许多实例 ,基本上都是选择性(selectivity)低的列。

    (4)索引中存储的是什么

    因为索引基本上是用来存储列值的数据结构,这使查找这些列值更加快速。
    如果索引使用最常用的数据结构 B-Tree,那么其中的数据是有序的。
    有序的列值可以极大的提升性能。下面解释原因:
    假设我们在 Employee_Name 这一列上创建一个 B-Tree 索引。这意味着当我们用之前的SQL查找姓名是‘Jesus’的雇员时,不需要再扫描全表。而是用索引查找去查找名字为‘Jesus’的雇员,因为索引已经按照按字母顺序排序。索引已经排序意味着查询一个名字会快很多,因为名字少字母为‘J’的员工都是排列在一起的。另外重要的一点是,索引同时存储了表中相应行的指针以获取其他列的数据。

    (5)索引存储指向数据库某行的指针

    如果我们在索引里找到某一条记录作为索引的列的值,如何才能找到这一条记录的其它值呢?

    数据库索引同时存储了指向表中的相应行的指针。指针是指一块内存区域, 该内存区域记录的是对硬盘上记录的相应行的数据的引用。

    因此,索引中除了存储列的值,还存储着一个指向其所在行数据的索引。

    也就是说,索引中的Employee_Name这列的某个值(或者节点)可以描述为 (“Jesus”, 0x82829), 0x82829 就是包含 “Jesus”那行数据在硬盘上的地址。如果没有这个引用,你就只能访问到一个单独的值(“Jesus”),而这样没有意义,因为你不能获取这一行记录的employee的其他值,例如地址(address)和年龄(age)。

    (6)数据库怎么知道什么时候使用索引

    当这个SQL (SELECT * FROM Employee WHERE Employee_Name = ‘Jesus’ )运行时,数据库会检查在查询的列上是否有索引。假设 Employee_Name列上确实创建了索引,数据库会接着检查使用这个索引做查询是否合理 ,因为有些场景下,使用索引比起全表扫描会更加低效。
    如果想要了解更多这些场景,请阅读这篇文章:SQL选择性值

    那么,什么时候最好使用数据库索引呢?

    好吧,当选择性值低时!为什么选择性低意味着使用索引不是一个好主意?好吧,想想看-假设我们要运行一个查询,以查找表中所有女性的名字-我们当然假设“性别”列之外还有“姓名”列。如果我们要搜索具有10,000行的表中的所有女性行,那么很有可能50%的行是女性,因为实际上只有两个可能的值-男性和女性。假设确实有50%的行是女性,那么这意味着我们必须访问索引5,000次才能找到所有的女性行。访问索引需要花费时间,并消耗资源。 如果我们要访问索引5,000次,则直接访问表并进行全表扫描实际上要快一些。因此,您可以看到查询优化器使用了选择性值来确定使用索引还是直接读取表更有效。

    通常来说, 开发者不会告诉数据库什么时候使用索引,这是由数据库自己决定。
    然而,值得注意的是在大多数数据库中(像Oracle 和 MYSQL), 你实际上可以制订你想要使用的索引。

    二、索引的优点

    第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
    第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
    第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
    第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
    第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能

    三、索引的缺点:

    数据库索引是创建在表的某列上的,并且存储了这一列的所有值。

    但是,需要理解的重点是数据库索引并不存储这个表中其他列(字段)的值

    举例来说,如果我们在Employee_Name列创建索引,那么列Employee_AgeEmployee_Address上的值并不会存储在这个索引当中。如果我们确实把其他所有字段也存储在个这个索引中,那就成了拷贝一整张表做为索引,这样会占用太大的空间而且会十分低效。

    1. 其一,索引会占用空间 ,你的表越大,索引占用的空间越大。
    2. 其二,性能损失(主要值更新操作),当你在表中添加、删除或者更新行数据的时候, 在索引中也会有相同的操作。记住:建立在某列(或多列)索引需要保存该列最新的数据

    基本原则是只如果表中某列在查询过程中使用的非常频繁,那就在该列上创建索引

    第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。

    第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果 要建立聚簇索引,那么需要的空间就会更大。

    第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维 护速度。

    相关文章

      网友评论

        本文标题:数据库索引

        本文链接:https://www.haomeiwen.com/subject/uiuryhtx.html