zoukankan      html  css  js  c++  java
  • 数据库(一)-------索引的本质、类型以及如何创建索引详解(基础)

    索引是数据库中非常重要的一部分。在查询中增加所以很多时候会比不加索引效率高很多。

    在我学习了索引如何使用后,我开始有一些问题,而最根本的原因就是我不知道本质上索引是什么,所以本文就是针对索引的本质来讲下他的原理的。但是只以BTREE为例,其他数据结构或则算法的索引原理会在其他文章讲解。

     

    1.什么是索引?

    首先,当我看见有一种索引的创建语句是如下的时候,create index index_name on table_name( column)。我是这样猜测的:我觉得索引首先是取出了一列或者几个特殊的列,然后把他们重命名为index_name,然后存起来了。存的方式就是用特殊的数据结构,比如二叉树。(因为我之前在学习数据结构的时候知道二叉树可以增加查询速度)。但是我不知道他是存在缓存还是哪里?

    (我个人习惯在学习一个东西的应用后思考它的本质是怎么回事,然后开始猜测,然后再找资料验证。这是我个人的学习习惯。)

    经过我查阅资料,我发现索引是一种数据结构。索引中是包含一个表中列的值和它的物理地址的值,并且这些值存储在一个数据结构中。

    注意:

                -------索引可以存储的数据结构有多种,常用的有二叉树,还是有哈希表。这个有很多。

               -------索引中存的数据:其中只存一个表中的一列或者多列。如果是单索引就是存一列,如果使用的是复合索引就是多列。但是注意不要多列的概念,如果我在一个employee表中有(employee_id,employee_name,employee_age)3个属性。

    eg: create index employee_name on employee(employee_name);  那么数据结构中只存employee_name的所有值和employee_name值相应的磁盘物理地址。至于employee_id和employee_age都不会在索引中存在。

    eg: create index employee_name on employee(employee_id employee_name)那么存的是employee_id 的值和employee_name的值。但是employee_age不会有。

                -------索引被创建后的位置。当我们只建立一个表的时候,我们只有.frm文件。当我们创建索引后,会出现.myi的索引文件。这个文件就是在my.ini中的path路径下(当然很多人找不到这个位置,方法我在这个文章中有写了,有需要的朋友可以链接:https://blog.csdn.net/qq_36098284/article/details/

     

    2.索引能用来干什么?

    当我们创建索引后,会增加查询的效率,多数情况下会比全表扫描要快。

    现在我们来解释一下,如果没有索引是怎么进行查询操作的?

    看下面的图片:当我们的select是查询empno=4的时候,dbms会生成一个类似指针的东西,从empno=1的地方开始搜索,一直搜索到表的结束,这里是empno=11.

    那么有人会问,为什么他搜索到empno=4为什么不停止呢?我们没有索引的select是全表扫描,就是必须把整个表都扫描一次后才告诉dbms,查询结果是什么?

    开始的时候我有一个问题,就是如果我们扫描的是主键,当他找到一个结果的时候,因为我用的是where语句,是不是就会停止,答案是,和扫描的是不是主键并没有关系。不添加index就是全表扫描。

    所以扫描结果会慢。

     

     

     

    现在我们再来看下,如果创建了索引会出现什么情况?为什么就会变快了?

    我们还是拿刚刚的举例子,当我们使用二叉树创建的索引,还要扫描empno这属性列的时候,4只需要和6.3.5.4比较4回就会找到结果,和刚刚的11次,相比快了很多。当数据越大的时候,速度就会快的更明显。因为每次都是减掉一半的数据。

    (具体的二叉树算法,或者二叉树的数据结构,请看该文,链接:)

     

     

     

    3.索引的分类

                     ---------索引类型:主键索引,普通索引,全文索引,唯一索引   

     3.1主键索引

            主键索引的添加:

                方法一: 在创建表的时候直接创建

                        create table table_name(id int unsiged primary key auto_increment,

                                                                name varchar(20) not null default ' ' );

                方法二:先创建表,后创建index

                        alter  table  table_name  add  primary  key  ( column_name );

            提问:在看完主键索引的创建方式后,你会不会和我一样,觉得这和主键的创建没有区别?

                答:主键是字段中唯一不为空值的列,主键是一种约束。同时主键索引是一种特殊的唯一索引。

                        那么创建主键的时候,数据库会默认为主键创建一个唯一索引,那会为主键创建一个主键索引吗?

                        他俩是一回事吗?(我在找下资料哈)

     

       3.2全文索引

     

       3.3普通索引

            普通索引就是针对普通的列,根据第4点(什么样的列适合做索引)而创建的索引。

            创建方式就是先创建表,根据需要选择要创建的索引列。

                create   index  index_name  on  table_name( column_name );

     

     

     

     3.4 唯一性索引

      

    更新中,一个小时候更新。

         3.5 索引的查询:

               方法一:

                          desc table_name【缺点:不能查到index的名字】

              方法二:

                           show  index(es)  from  table_name G

     

     

     

     3.6 索引的删除:

                    alter  table  table_name  drop  index  index_name;

     

    4.哪些时候需要用到索引?

           

            ------当这个语句被频繁用作where条件的查询时,最好创建索引

            ------该字段的列的值很丰富的时候,不是唯一几个值时可以创建索引(比如唯一性太差不适合,例如sex)

            -------更新频率不是十分频繁的时候(如果这个列的数据的变化十分的频繁,那么频繁的更改索引文件,会有更多的消耗)

     

    5.使用索引的时候需要注意什么?

             ------ 使用索引的时候是有代价的:比如占用磁盘的代价;或者对dml(update,insert,destroy)操作的影响。

                              所以说创建索引增加的效率多数就是对select的,对dml其实是副作用。

              ------- 对于复合索引来说,只是查询条件使用了最左面的列,索引才会有作用。(复合索引就是多列了)

                            eg: create  index dept add index my_ind(dname,loc);

                                //dname为最左面的列,loc为右面的列。

                                失效:select * from dept where loc ='aaa'; 就是这个语句其实在查询的时候没有用到索引。

             -------- 对于用模糊查询,查询结果如果是“%aaa”不会使用索引,“aaa%”会使用索引。

                            关于模糊查询请链接:

     

    原文:https://blog.csdn.net/qq_36098284/article/details/79841094

  • 相关阅读:
    哪种写法更好?<script></script> vs/or <script type=”text/javasript”></script>
    JS 脚本应该放在页面哪个位置 head body foot
    List<T> ForEach break
    嵌套JSON 取出name与value
    C# 改变图片尺寸(压缩),Image Resize
    tornado
    appachebench网站压力测试
    mysql分区分表
    redis的持久化存储,RDB与AOF
    MEMCACHE的内存管理和删除策略
  • 原文地址:https://www.cnblogs.com/sucretan2010/p/13791463.html
Copyright © 2011-2022 走看看