zoukankan      html  css  js  c++  java
  • 数据库索引

    一、索引简介

    1.索引是什么?

    MySQL官对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。即得到索引的本质:索引是数据结构。

    1)你可以理解为“排好序的快速查找数据结构”。

    详解(重要):

      在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。下图就是一种可能的索引方式示例:

                 

                   左边是数据表,一共有两列七条记录,最左边的是数据存储的物理地址。

      为了加快 Col2 的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录地址的指针,这样就可以运用二叉查找树在一定的复杂度内获取到相应数据,从而快速的检索出符合条件的记录。

    我们平时所说的索引,如果没有特别指明,都是指 B 树(多路搜索树,并不一定是二叉树)结构组织的索引。其中聚集索引,次要索引,覆盖索引,复合索引,前缀索引,唯一索引默认都是使用 B+树索引,统称索引。当然,除了B+树这种类型的索引之外,还有哈希索引(hash index)等。

    2.索引的优势和劣势

    优势:

    • 类似大学图书馆建书目索引,提高数据检索的效率,降低数据库的IO成本。
    • 通过索引列队数据进行排序,降低数据排序的成本,降低了CPU的消耗。

    劣势:

    • 实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用空间的。
    • 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对标进行insert、update和delete。因为更新表时,MySQl不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新索带来的键值变化后的索引信息。
    • 索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询。

    3.MySQL的索引分类

    1)单值索引

    即一个索引值包含单个列,一个表可以有多个单列索引

    创建方法:

    a. 建表的时候一起创建

      CREATE TABLE mytable ( name VARCHAR(32) , INDEX index_mytable_name (name) );

    b. 建表后,直接创建索引

      CREATE INDEX index_mytable_name ON mytable(name);

    c. 修改表结构

      ALTER TABLE mytable ADD INDEX index_mytable_name (name);

    注:如果是字符串字段,还可以指定索引的长度,在列命令后面加上索引长度就可以了(例如:name(11))

    2)唯一索引

    索引列的值必须是唯一的,但允许有空值。(银行卡号)

    创建方法:

    a. 建表的时候一起创建

      CREATE TABLE mytable ( `name` VARCHAR(32) , UNIQUE index_unique_mytable_name              (`name`) );

    b. 建表后,直接创建索引

      CREATE UNIQUE INDEX index_mytable_name ON mytable(name);

    c. 修改表结构

      ALTER TABLE mytable ADD UNIQUE INDEX index_mytable_name (name);

    注:如果是字符串字段,还可以指定索引的长度,在列命令后面加上索引长度就可以了(例如:name(11))

    3)复合索引

    即一个索引包含多个列。

    创建方法:

    a. 建表的时候一起创建

      CREATE TABLE mytable ( `id` int(11) , `name` VARCHAR(32) , INDEX index_mytable_id_name            (`id`,`name`) );

    b. 建表后,直接创建索引

      CREATE INDEX index_mytable_id_name ON mytable(id,name);

    c. 修改表结构

      ALTER TABLE mytable ADD INDEX index_mytable_id_name (id,name);

    4)主键索引

    是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引。

    创建方法:

    a. 建表的时候一起创建

      CREATE TABLE mytable ( `id` int(11) NOT NULL AUTO_INCREMENT , `name` VARCHAR(32)   , PRIMARY KEY (`id`) );

    b. 修改表结构

      ALTER TABLE test.t1 ADD CONSTRAINT t1_pk PRIMARY KEY (id);

    注:如果是字符串字段,还可以指定索引的长度,在列命令后面加上索引长度就可以了(例如:name(11))

    5)全文索引

    主要用来查找文本中的关键字,而不是直接与索引中的值相比较。

    fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。

    fulltext索引配合match against操作使用,而不是一般的where语句加like。

    它可以在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上可以创建全文索引。

    创建方法:

    a. 建表的时候一起创建

      CREATE TABLE `article` ( `id` int(11) NOT NULL AUTO_INCREMENT ,`title` char(250) NOT NULL   , `contents` text NULL , `create_at` int(10) NULL DEFAULT NULL , PRIMARY KEY (`id`), FULLTEXT   (contents) );

    b. 建表后,直接创建索引

      CREATE FULLTEXT INDEX index_article_contents ON article(contents);

    c. 修改表结构

      ALTER TABLE article ADD FULLTEXT INDEX index_article_contents (contents);

    6)基本语法

    创建:

    ① create [unique] index indexName on mytable(columnName(length));

    ② alert mytable add [unique] index [indexName] on (columnName(length));

    删除:

    drop index [indexName] on mytable;

    查看:

    show index from table_nameG

    4.MySQL索引结构

    1)B+ 树

     【初始化介绍】

    一颗 B+ 树,浅蓝的的快我们成为磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项17和35,包含指针P1,P2,P3。

    P1表示洗浴17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。

    真实的数据存在于叶子节点即3、5、9、10、13、15、28、29、36、60、75、79、90、99。

    非叶子节点不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。

    【查找过程】

      如果要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次I口, 在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的I0)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次I0,29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次I0,同时内存中做二分查找找到29,结束查询,总计三次I0。

      真实的情况是,3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次I0,性能提高将是巨大的,如果没有索引,每个数据项都要发生一次I0,那么总共需要百万次的I0,显然成本非常非常高。

    5.哪些情况需要创建索引?
    1)主键自动建立唯一索引。

    2)频繁作为查询条件的字段应该创建索引。

    3)查询中与其他表关联的字段,外键关系建立索引。

    4)单键/组合索引的选择问题?(在高并发下倾向创建组合索引)。

    5)查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度。

    6)查询中统计或者分组字段。

    6.哪些情况不需要创建索引?

    1)表记录太少

    2)经常增删改的表,why:提高了查询速度,同时却会降低更新表的速度,如对表进行insert、update、delete,因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

    3)where 条件里用不到的字段不创建索引。

    4)数据重复且分布均匀的表字段,因此应该只为最经常查询和最经常排序的数据列建立索引。注意,如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。

  • 相关阅读:
    学生分数排序
    union 的一个简单例子,搜狗笔试题
    枚举的初始化赋值
    unsigned 赋值负数输出情况 & printf输出格式
    sizeof中的表达式不执行
    三级指针:百度试题
    生成器案例,#采集日志
    简述装饰器
    装饰器(转载)
    python写监控并发警报邮件
  • 原文地址:https://www.cnblogs.com/BeenTogether/p/13096088.html
Copyright © 2011-2022 走看看