zoukankan      html  css  js  c++  java
  • Mysql索引及执行计划(之索引)部分

    索引及执行计划

    1. 介绍

    相当于一本书中的目录,可以加速查询(select ,update,delete ).
    

    2.种类

    Btree (平衡多叉树): b-tree b+tree(b*tree),优点:范围查找
    HASH : 优点,比较适合随机的等值.
    Rtree
    2. MySQL 支持的索引类型(算法)
    Btree    : 平衡多叉树
    Rtree    :空间树所以
    Hash     :HASH索引
    Fulltext :全文索引
    

    3.btree的细分

    聚簇索引 : 主键索引
    辅助索引 :
    单列
    联合
    唯一
    前缀
    #MySQL Btree索引的应用
    聚簇索引(聚集索引、主键索引)
    前提: 
    	0. InnoDB存储引擎的表才会有聚簇索引。
    	1. 有主键,主键就是聚簇索引
    	2. 没有主键,选择唯一键作为聚簇索引
    	3. 没有主键和唯一键生成一个隐藏列(DB_ROW_ID,6字节),作为聚簇索引
    作用: 
    	1. 聚簇(区)索引,组织表(IOT): 所有数据在插入时,都按照ID(主键)属性,在相邻数据页上有序存储数据。
    	2. 加快存储数据,加快通过索引作为查找条件的查询。
    	#参考网址 https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html
    

    4.索引的构建过程

    聚簇索引构建过程
    1. 叶子节点 : 
    	由于存储数据时,已经按照ID顺序在各个数据页中有序存储了,所以《原表数据》所在数据页被作为叶子节点。
    2. 内部节点(非叶子节点): 
       获取叶子节点ID范围+指针。
    3. 根节点: 
       获取非叶子节点 ID范围+指针
    辅助索引构建过程: 
    	1. 叶子节点构建: 
    		提取索引列值+ID ,进行从小到大排序(辅助索引列值),存储到各个数据页,作为Leaf node。
    	2. 非叶子节点(internel node )
    		提取下层的辅助索引列值范围+指针。
        3. 根节点: 
    		提取下层节点的范围+指针。
    对于查询的优化:
    	1. 通过辅助索引列,进行条件查询,根据辅助索引BTREE快速锁定条件值对应的ID。
    	2. 通过得出的ID值,回到聚簇索引继续查询到具体的数据行(回表)。
    

    5.辅助索引的分类

    普通单列
    联合索引
    	idx(a,b)
    	叶子节点:  
    		 id+a+b ,按照a和b进行排序,生成叶子节点
    	枝节点和根节点: 
    		 只会包含最左列(a列)的范围+指针
        注意: 最左原则
    			1. 建索引,最左列重复值少的。
    			2. 查询条件中,必须包含最左列。
    唯一索引
    	unique key 
    
    前缀索引
    	idex(test(10))
    

    6.回表是什么

    辅助索引扫描之后,得到ID,再回到聚簇索引查找的过程.
    

    6.1 会表带来什么问题

    IO : 次数和量会增加.
    IOPS : 1000次/s
    吞吐量 : 300M/s
    

    6.2 咋样减少回表

    a. 建索引使用联合索引(覆盖),尽可能多将查询条件的数据包含联合索引中.
    b. 精细查询条件(业务方面,> and < ,limit)
    c. 查询条件要符合联合索引规则,覆盖的列越多越好.
    

    7.索引的管理

    7.1压测

    mysql> source /root/t100w.sql
    mysql> grant all on *.* to root@'10.0.0.%' identified by '123';
    ## /root/t100w.sql 这个表放在博客园文件当中
    [root@oldboy ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='test' --query="select * from test.t100w where k2='780P'" engine=innodb --number-of-queries=2000 -uroot -p123 -h10.0.0.50  -verbose
    
    --concurrency=100  :  模拟同时100会话连接
    --create-schema='test' : 操作的库是谁
    --query="select * from test.t100w where k2='780P'"  :做了什么操作
    --number-of-queries=2000 : 一共做了多少次查询
    
    mysqlslap: [Warning] Using a password on the command line interface can be insecure.
    Benchmark
    	Running for engine rbose
    	Average number of seconds to run all queries: 741.086 seconds
    	Minimum number of seconds to run all queries: 741.086 seconds
    	Maximum number of seconds to run all queries: 741.086 seconds
    	Number of clients running queries: 100
    	Average number of queries per client: 20
    
    

    7.2查询表的索引

    desc t100w;  
    +-------+-----------+------+-----+-------------------+-----------------------------+
    | Field | Type      | Null | Key | Default           | Extra                       |
    +-------+-----------+------+-----+-------------------+-----------------------------+
    | id    | int(11)   | YES  |     | NULL              |                             |
    | num   | int(11)   | YES  |     | NULL              |                             |
    | k1    | char(2)   | YES  |     | NULL              |                             |
    | k2    | char(4)   | YES  |     | NULL              |                             |
    | dt    | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
    +-------+-----------+------+-----+-------------------+-----------------------------+
    5 rows in set (0.00 sec)
    
    -----
     Key 
    -----
    PK     --> 主键(聚簇索引)     
    MUL    --> 辅助索引   
    UK     --> 唯一索引  
         
    mysql> show index from t100w;
    

    8.创建索引

    8.1单列辅助索引

    mysql> select * from test.t100w where k2='780P';
    优化方式: 
    语法:
    alter table 表名 add index 索引名(列名);	
    alter table t100w add index idx_k2(k2);
    

    8.2联合索引创建

    mysql> alter table t100w add index idx_k1_num(k1,num);
    Query OK, 0 rows affected (3.39 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    

    8.3 前缀索引创建

    判断前缀长度多少合适:
    select count(distinct(left(name,5)))  from city ;
    select count(distinct name)  from city ;
    创建前缀索引
    mysql> alter table city add index idx_n(name(5));
    

    8.4 删除索引

    mysql> alter table city drop index idx_n;
    Query OK, 0 rows affected (0.00 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    
  • 相关阅读:
    [已解决]报错:报错AttributeError: 'int' object has no attribute 'upper'
    Pandas之read_excel()和to_excel()函数解析
    [已解决]报错This event loop is already running
    [转]NMON服务器监控、指标说明
    LoadRunner编程之跳出迭代
    sqlplus与shell互相传值的几种情况
    Loadrunner中socket协议中的三个关联函数
    ORACLE expdp/impdp导出实例
    Linux下的split 命令(将一个大文件根据行数平均分成若干个小文件)
    批量快速的导入导出Oracle的数据(spool缓冲池、java实现)
  • 原文地址:https://www.cnblogs.com/lailaoban/p/14769112.html
Copyright © 2011-2022 走看看