• 数据库操作之——索引


    一 索引的概念

    MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。

    打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。

    创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。

    实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

    上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

    建立索引会占用磁盘空间的索引文件。

    二 B-tree

      B-Tree 索引是 MySQL 数据库中使用最为频繁的索引类型,除了 Archive 存储引擎之外的其他所有的存储引擎都支持 B-Tree 索引。不仅仅在 MySQL 中是如此,实际上在其他的很多数据库管理系统中B-Tree 索引也同样是作为最主要的索引类型,这主要是因为 B-Tree 索引的存储结构在数据库的数据检 索中有非常优异的表现。 
          一般来说, MySQL 中的 B-Tree 索引的物理文件大多都是以 Balance Tree 的结构来存储的,也就是所有实际需要的数据都存放于 Tree 的 Leaf Node ,而且到任何一个 Leaf Node 的最短路径的长度都是完全相同的,所以我们大家都称之为 B-Tree 索引当然,可能各种数据库(或 MySQL 的各种存储引擎)在存放自己的 B-Tree 索引的时候会对存储结构稍作改造。如 Innodb 存储引擎的 B-Tree 索引实际使用的存储结构实际上是 B+Tree ,也就是在 B-Tree 数据结构的基础上做了很小的改造,在每一个 
    Leaf Node 上面出了存放索引键的相关信息之外,还存储了指向与该 Leaf Node 相邻的后一个 LeafNode 的指针信息,这主要是为了加快检索多个相邻 Leaf Node 的效率考虑。 

    三  索引的具体介绍

      mysql的索引分为单列索引(主键索引,唯索引,普通索引)和组合索引.

      单列索引:一个索引只包含一个列,一个表可以有多个单列索引.

      组合索引:一个组合索引包含两个或两个以上的列。

      1 索引的创建

      1)单列索引

      1-1 普通索引,这是最基本的索引

      方法一

    mysql> create index in_id on s1(id);
    Query OK, 0 rows affected (0.82 sec)

      方法二

    mysql> alter table s1 add index in_id (id);
    Query OK, 0 rows affected (0.79 sec)

      1-2 唯一索引

      创建方法与普通索引类似

      方法一

    mysql> create unique index uni_id on s1(id);
    Query OK, 0 rows affected (0.77 sec)
    Records: 0  Duplicates: 0  Warnings: 0

      方法二

    mysql> alter table s1 add unique index uni_id (id);
    Query OK, 0 rows affected (0.77 sec)
    Records: 0  Duplicates: 0  Warnings: 0

      1-3 主键索引

      主键索引,不允许有空值,(在B+TREE中的InnoDB引擎中,主键索引起到了至关重要的地位)

      主键索引建立的规则是 int优于varchar,一般在建表的时候创建,最好是与表的其他字段不相关的列或者是业务不相关的列.一般会设为 int 而且是 AUTO_INCREMENT自增类型的。

      2)组合索引

      一个表中含有多个单列索引不代表是组合索引,通俗一点讲 组合索引是:包含多个字段但是只有索引名称,期格式是CREATE INDEX IndexName On `TableName`(`字段名`(length),`字段名`(length),...)。  

      使用多列所需需要按照最左索引列查找;不能跳过中间列(跳过就会将遍历被跳过的索引字段,会浪费大量时间);如果某一列是范围查询,那么其右边所有列无法使用索引。

      列的顺序非常重要,MySQL仅能对索引最左边的前缀进行有效的查找。例如:假设存在组合索引it1c1c2(c1,c2),查询语句select * from t1 where c1=1 and c2=2能够使用该索引。查询语句select * from t1 where c1=1也能够使用该索引。但是,查询语句select * from t1 where c2=2不能够使用该索引,因为没有组合索引的引导列,即,要想使用c2列进行查找,必需出现c1等于某值。

      示例:

    mysql> create  index mul_index on s1(id,name,email);
    Query OK, 0 rows affected (0.59 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    mysql> desc s1;
    +--------+-------------+------+-----+---------+-------+
    | Field  | Type        | Null | Key | Default | Extra |
    +--------+-------------+------+-----+---------+-------+
    | id     | int(11)     | YES  | MUL | NULL    |       |
    | name   | varchar(20) | YES  |     | NULL    |       |
    | gender | char(6)     | YES  |     | NULL    |       |
    | email  | varchar(50) | YES  |     | NULL    |       |
    +--------+-------------+------+-----+---------+-------+
    4 rows in set (0.01 sec)

      如示例所示创建了一个组合索引(id,name,email),实际上是创建了一下这几种索引。

      (id),(id,name,),(id,email),(id,name,email)。

    mysql> select count(1) from s1 where name='egon' and email = 'egon160000@oldboy';
    +----------+
    | count(1) |
    +----------+
    |        1 |
    +----------+
    1 row in set (0.08 sec)
    
    mysql> select count(1) from s1 where id =830 and email = 'egon160000@oldboy';
    +----------+
    | count(1) |
    +----------+
    |        0 |
    +----------+
    1 row in set (0.00 sec)

      演示结果,带有id的查询命令会快很多。

      重点:最左前缀原则。

      所谓最左前缀原则就是先要看第一列,在第一列满足的条件下再看左边第二列,以此类推。有位网友描述得很形象: 你可以认为联合索引是闯关游戏的设计例如你这个联合索引是state/city/zipCode那么state就是第一关 city是第二关, zipCode就是第三关你必须匹配了第一关,才能匹配第二关,匹配了第一关和第二关,才能匹配第三关你不能直接到第二关的索引的格式就是第一层是state,第二层才是city索引是因为B+树结构 所以查找快 如果单看第三列 是非排序的。 

      多列索引是先按照第一列进行排序,然后在第一列排好序的基础上再对第二列排序,如果没有第一列的话,直接访问第二列,那第二列肯定是无序的,直接访问后面的列就用不到索引了。 
      所以如果不是在前面列的基础上而是但看后面某一列,索引是失效的。

      示例:

        

      

    二 索引的删除

      不管是普通索引还是唯一索引,固定格式

      DORP INDEX IndexName ON `TableName`

    mysql> drop index mul_index on s1;
    Query OK, 0 rows affected (0.41 sec)
    Records: 0  Duplicates: 0  Warnings: 0
  • 相关阅读:
    js广告随窗口滚动小案例
    CSS中Float概念相关文章
    图片展示javascript各类型的关系
    ajax调用异常
    设置修改 Apache 文件根目录 (Document Root)
    SQL查询今天与昨天的记录,及本月记录、本周记录
    服务器角色
    javaScript进阶昂贵的集合
    .net实体新解
    数组操作时避免空值出现
  • 原文地址:https://www.cnblogs.com/654321cc/p/7755458.html
Copyright © 2020-2023  润新知