zoukankan      html  css  js  c++  java
  • 索引

    什么是索引

    索引的本质是一个特殊的文件,是存储引擎快速找到记录的一种数据结构。

    类比:查字典的过程,通过拼音索引

    索引的本质:通过不断地缩小想要获取数据地范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。

    为什么要使用索引

    使用索引就是为了提高查询效率

    索引的底层原理

    使用B+树

    索引的种类

    • 主键索引:加速查找、不为空、不能重复

    • 唯一索引:加速查询、不为空的字段不能重复

    • 联和唯一索引:unique(name, password)

    • 普通索引:加速查找 index(name)

    • 联合索引:index(name, password)

    索引的创建

    主键索引

    新增主键索引

    --创建的时候增加主键索引
    create table t1(
    	id int auto_increment primary key,
        name varchar(32) not null default ''
    )charset utf8;
    
    
    --表创建完了之后再增加主键索引
     alter table t2 add primary key(id);
     
     
    

    删除主键索引

    --删除主键索引
    alter table t2 drop primary key;
    

    唯一索引

    新增唯一索引

    --创建表的时候增加唯一索引
    mysql> create table t2(
        -> id int auto_increment primary key,
        -> name varchar(32) not null default '',
        -> unique(name)    # 如果不设定唯一键的名字,默认唯一键的名字是作用的字段名
        -> )charset utf8;
        
        
        
    --创建表后新增唯一索引键
    # create unique index 索引名 on 表名(字段名);
    create unique index un_name on t2(name);
    
    --或者
    alter table t2 add unique key(name);
    --或者
    alter table t2 add unique index un_name(name);
    

    删除唯一索引键

    alter table t2 drop index name;  # index后面是唯一键的名字
    

    普通索引

    新增

    --创建表的时候新增普通索引
    create table t3(
    	id int auto_increment primary key,
        name varchar(32) not null default '',
        index u_name(name)   # index后面跟的是索引的名字,可以不写
    )charset utf8;
    
    --创建表后创建普通索引
    create index 索引名 on 表名(字段名);
    
    create index ix_name on t3(name);
    
    
    --或者
    alter table t3 add index ix_name (name);
    

    删除

    alter table t3 drop index u_name;
    

    索引的优缺点

    通过观察*.ibd文件可知:

    • 索引加快了查询速度
    • 但是加了索引之后,会占用大量的磁盘空间

    索引不是加的越多越好

    不会命中索引的情况

    • 不能在SQL语句中,进行四则运算,会降低sql的查询效率
    • 使用函数 如:select * from t1 where reverse(name)='abc1213';
    • 类型不一致
      • 如果列是字符串类型,传入条件必须要用引号引起来,如select * from t1 where email=1241;
    • order by 当排序条件为索引,则select字段必须也是索引字段,否则无法命中
      • select email from t1 order by email desc;
      • 如果对主键排序,速度还是很快的
    • count(1)或count(列)代替count(*)在mysql中没有差别
    • 组合索引最左前缀

    组合索引最左前缀

    什么时候会创建联合索引?

    根据公司的业务场景,在最常用的几列上添加索引

    select * from user where name='abc123' and email='abc123@qq.com'
    
    遇到上述业务情况,错误的做法:
    index ix_name(name),
    index ix_email(email)
    
    
    正确的做法:
    index ix_name_email(name, email)
    
    

    如果组合索引为:ix_name_email (name, email)

    那么:

    where name='abc' and email='xxx'   --索引命中
    where name='abc'                   --命中索引
    where email='abc123@qq.com'        --未命中索引
    

    explain查询性能分析

    mysql> explain select * from t1 where id=2141G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: t1
       partitions: NULL
             type: const
    possible_keys: PRIMARY
              key: PRIMARY
          key_len: 4
              ref: const
             rows: 1
         filtered: 100.00
            Extra: NULL
    1 row in set, 1 warning (0.00 sec)
    

    各个参数的含义:

    • id:这是select的查询序列号

    • select_type:是select的类型

    • table:显示这一行的数据是关于哪张表的

      • type:这列最重要,显示了连接使用了哪种类别,有无使用索引,是使用Explain命令分析性能瓶颈的关键项之一
      结果值从好到坏依次是:
      
      system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
      
      一般来说,得保证查询至少达到range级别,最好能达到ref,否则就可能会出现性能问题。
      
    • possible_keys:列出MySQL能使用哪个索引在该表中找到行

    • key:显示MySQL实际使用的索引

    • key_len:索引长度

    • ref:显示使用哪个列或常数与key一起从表中选择行。

    • rows:扫描的长度

    • Extra:使用到了索引

    索引覆盖:

    select id from t1 where id=2132123;

    当字段id 添加了主键索引,这时候是命中索引的;但查询了字段id,id本身有主键索引,这时候会产生索引覆盖,会比主键索引快。

    慢查询日志

    查看慢SQL的相关变量

    mysql> show variables like '%slow%';
    +---------------------------+-----------------------------------------------+
    | Variable_name             | Value                                         |
    +---------------------------+-----------------------------------------------+
    | log_slow_admin_statements | OFF                                           |
    | log_slow_slave_statements | OFF                                           |
    | slow_launch_time          | 2                                             |
    | slow_query_log            | OFF                                           |
    | slow_query_log_file       | D:mysql-5.7.28dataDESKTOP-PAT2F9O-slow.log |
    +---------------------------+-----------------------------------------------+
    

    查看慢sql查询时间配置

    mysql> show variables like '%long%';
    +----------------------------------------------------------+-----------+
    | Variable_name                                            | Value     |
    +----------------------------------------------------------+-----------+
    | long_query_time                                          | 10.000000 |
    | performance_schema_events_stages_history_long_size       | 10000     |
    | performance_schema_events_statements_history_long_size   | 10000     |
    | performance_schema_events_transactions_history_long_size | 10000     |
    | performance_schema_events_waits_history_long_size        | 10000     |
    +----------------------------------------------------------+-----------+
    

    设置慢SQL日志配置

    --开启慢SQL查询
    set global  slow_query_log = on;
    
    --设置慢SQL查询日志的路径
    set global slow_query_log_file = "D:/mysql-5.7.28/data/mysql_slow";
    
    --设置慢SQL查询时间
    set global long_query_time = 2;
    
  • 相关阅读:
    poj3673
    poj3438
    poj3461
    poj3518
    poj3672
    变秃了,也变强了!爆肝吐血整理出的超硬核JVM笔记分享!
    左手字节,右手阿里,我是如何通阿里架构师的java面试文档,拿到多家大厂offer的
    Java异常处理与常用类
    copy_{to, from}_user()的思考
    vi文本编辑器常用指令功能
  • 原文地址:https://www.cnblogs.com/setcreed/p/11774146.html
Copyright © 2011-2022 走看看