• 数据库索引使用方式


    使用索引是提高数据库查询效率的主要方式,下面从索引结构,索引类型,索引操作,命中索引几个方面来介绍索引。

    一、索引结构

    mysql5.5以上的默认存储引擎innodb,只显式支持BTree( 事实上从数据结构上来讲是B+树,mysql称之为BTree)索引,对于频繁访问的表,innodb会建立自适应hash索引,

    即在B树索引基础上建立hash索引,可以显著提高查找效率,用户是无法自己指定的,除此之外还有Hash索引和全文索引(fullText索引)。 

    BTree索引 

    BTree,顾名思义,就是所有的索引节点都按照balance tree的数据结构来存储。BTree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度。

    Btree中,每个结点包含: 

    1、本结点所含关键字的个数;

    2、指向父结点的指针;

    3、关键字;

    4、指向子结点的指针; 

    更详细的B+树介绍参考https://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html

    Hash索引 

    Hash 索引由于使用了hash表结构,其检索效率很高,索引的检索可以一次定位,不像B+树索引需要从根节点到枝节点,

    所以 Hash 索引的查询效率要远高于 B+树 索引。但是,Hash索引的使用范围非常有限。

        1.在MySQL中,只有HEAP/MEMORY引擎表才能支持哈希索引,InnoDB引擎的自适应哈希索引(adaptive hash index)不

       能在创建索引时指定。

       2.Hash索引仅支持=,>=,<=这几种条件运算,不支持排序,范围内查找,like等查询。

       3.Hash索引不支持组合索引中部分索引的查找。

       4.当Hash值重复较多时,索引速度可能不如BTree索引。

    FullText索引

    Full-text索引就是我们常说的全文索引,他的存储结构也是Btree。主要是为了解决在我们需要用like查询的低效问题。

    只能解决’xxx%’的like查询。如:字段数据为ABCDE,索引建立为A、AB、ABC、ABCD、ABCDE五个。

    二、索引类型

    索引一般有:普通索引,唯一索引,复合索引这几种类型。

    唯一索引:唯一索引要求字段中不会出现重复数据。

    复合索引:将多个字段组合起来作为索引,必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用。

    三、索引操作

    建立索引:

     create index 索引名 on 表名(索引字段名)

    建立唯一索引:

     create unique index 索引名 on 表名(索引字段名)

    建立复合索引:

    create index 索引名 on 表名(索引字段名1,索引字段名2...)

    查看表中索引:

    show index from 表名

    删除索引:

    drop index 索引名 on 表名

    查看索引是否命中

    Mysql:当结果的type为 index时索引命中

    explain +sql语句

    Oracle:

    explain plan for+sql语句

    四、命中索引

    1. 避免判断null

    应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

    select id from t where num is null

    可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

    select id from t where num=0

    2. 避免不等值判断

    应尽量避免在 where 子句中使用!=<>操作符,否则引擎将放弃使用索引而进行全表扫描。

    3. 避免使用or逻辑

    应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,

    select id from t where num=1 or num=2

    可以使用union all来进行查询来命中索引如:

    select id from t where num=1 union all select id from t where num=2

    4 . 慎用innot in逻辑

    in not in 也要慎用,否则会导致全表扫描,如:

    select id from t1 where num in(select id from t2 where id > 10)

    此时外层查询会全表扫描,不使用索引。可以修改为:

    select id from t1,(select id from t1 where id > 10)t2 where t1.id = t2.id

    此时索引被使用,可以明显提升查询效率。

    5. 注意模糊查询

    下面的查询也将导致全表扫描:

    select id from t where name like '%abc%'

    不要在like条件左边加'%',这样不会走索引模糊查询如果是必要条件时,可以使用

    select id from t where name like 'abc%'

    来实现模糊查询,此时索引将被使用。如果头匹配是必要的,可以使用elasticsearch等全文搜索引擎

    6. 避免查询条件中字段计算

    应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:

    select id from t where num/2=100

    应改为:

    select id from t where num=100*2

    7. 避免查询条件中对字段进行函数操作

    应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:

    select id from t where substring(name,1,3)='abc'

    nameabc开头的id

    应改为:

    select id from t where name like 'abc%'

    8. “=”左边避免表达式运算

    不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

    9. 组合索引使用

    在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

    10 exists

    很多时候用 exists 代替 in 是一个好的选择:

    select num from a where num in(select num from b)

    用下面的语句替换:

    select num from a where exists(select 1 from b where num=a.num)
  • 相关阅读:
    Smobiler实现手机弹窗
    在 ASP.NET Web API 中使用 Attribute 统一处理异常
    VMWare的网络模式说明
    Windows Server2008 IIS通过Nginx实现绑定多个https域名
    Error while Launching activity
    Android 动态渐变按钮
    mysql安装和配置详解以及Navicat连接失败问题
    selenium的基础学习
    使用Pandas.read_csv时出现OSError: Initializing from file failed
    sklearn 机器学习 Pipeline 模板
  • 原文地址:https://www.cnblogs.com/coder-lichao/p/10940338.html
Copyright © 2020-2023  润新知