• MySQL索引的创建和使用


    一、索引

    索引是快速查询的关键,MySQL索引的建立对于MySQL的高效运行是很重要的,对于较少的数据量,有没有索引可能没什么影响,但是当数据量较大时,查询性能会急剧下降,特别是进行条件查询的时候

    二、索引的类型

    • 1、主键索引 PRIMARY KEY
      主键索引是一种特殊的唯一索引,它不允许有空值,一般在创建表的时候创建,而且一个表只能有一个主键
      创建表的时候创建主键
    CREATE TABLE test(
    id int(0) NOT NULL AUTO_INCREMENT,
    hotelName varchar(255) DEFAULT NULL,
    PRIMARY KEY('id')
    );
    

    使用ALTER命令添加主键

    ALTER TABLE test ADD PRIMARY KEY('id');
    
    • 2、普通索引
      这是最基本的索引,没有做任何限制
      创建表的时候指定
    CREATE TABLE test(
    id int(0) NOT NULL AUTO_INCREMENT,
    hotelName varchar(255) DEFAULT NULL,
    PRIMARY KEY('id'),
    INDEX `hotelName`(`hotelName`)
    );
    

    使用ALTER命令添加普通索引

    ALTER TABLE test ADD INDEX hotelName(hotelName)
    
    • 3、唯一索引 UNIQUE
      唯一索引列的值必须是唯一的,可以有空值,如果是组合索引,那么列值的组合必须是唯一的
      创建表的时候指定
    CREATE TABLE test(
    id int(0) NOT NULL AUTO_INCREMENT,
    hotelName varchar(255) DEFAULT NULL,
    PRIMARY KEY('id'),
    UNIQUE INDEX `hotelName`(`hotelName`)
    );
    

    使用ALTER命令添加唯一索引

    ALTER TABLE test ADD UNIQUE hotelName(hotelName)
    
    • 4、组合索引
      就是一个索引包含多个列
      使用ALTER命令添加添加组合索引
    ALTER TABLE test ADD INDEX indexName(列1, 列2, 列3....)
    
    • 5、全文索引 FULLTEXT
      全文索引也是MyISAM的一个特殊索引类型,主要用于全文索引,InnoDB从Mysql5.6版本开始支持全文索引。
      创建表的时候指定
    CREATE TABLE test(
    id int(0) NOT NULL AUTO_INCREMENT,
    hotelName varchar(255) DEFAULT NULL,
    PRIMARY KEY('id'),
    FULLTEXT INDEX `hotelName`(`hotelName`)
    );
    

    使用ALTER命令添加添加全文索引

    ALTER TABLE test ADD FULLTEXT (hotelName)
    

    三、创建索引的一般原则

    • 1、对于查询频率高的字段创建索引

    索引的主要目的就是为了提升查询的所读,所以在查询频率高的字段上要创建索引

    • 2、对排序、分组、联合查询频率高的字段创建索引

    • 3、索引的数量尽量要少,不要创建不必要的索引

    没创建一个索引都会占用相应的物理控件
    过多的索引会导致insert、update、delete语句的执行效率降低

    • 4、如果需要将多列设置为索引时,可以采用多列索引

    • 5、选择唯一性索引

    唯一性索引的值时唯一的,可以更快速的通过该索引来确定某条记录

    • 6、尽量使用数据量少的索引

    如果索引的值很长,那么查询速度会受到影响

    • 7、尽量使用前缀来索引

    如果索引字段的值很长,最好使用值的前缀来索引

    • 8、删除不在使用或者很少使用的索引

    对于一些不经常使用的索引,应当及时的删除,从而减少索引对更新操作的影响

    四、执行计划 EXPLAIN

    通过使用MySQL的执行计划来查看sql语句的执行效率,分析执行计划的各个显示内容,找出查询效率低的原因

    EXPLAIN SELECT hotelID,c.city FROM hotelInfoApi as h, (SELECT city FROM hotelInfoApi GROUP BY city) as c WHERE h.city=c.city 
    

    • 执行计划的id
      select 查询的序列号,表示执行的顺序
    • id相同,执行顺序由上至下
    • id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
    • 执行计划的select_type
      查询的类型,主要用于区分普通查询、联合查询、子查询等
    • SIMPLE:简单的select查询,查询中不包含子查询或者union
    • PRIMARY:查询中包含子查询,最外层查询则被标记为primary
    • SUBQUERY/MATERIALIZED:SUBQUERY表示在select或where列表中包含了子查询,MATERIALIZED:表示 where 后面 in 条件的子查询
    • UNION:表示 union 中的第二个或后面的 select 语句
    • UNION RESULT: union的结果
    • DERIVED:派生表
    • 执行计划的table
      查询涉及到的表
    • 直接显示表名或者表的别名
    • <unionM,N> 由 ID 为 M,N 查询 union 产生的结果
    • 由 ID 为 N 查询产生的结果
    • 执行计划的type
      访问类型, SQL查询优化中的一个很重要的指标,结果值从好到坏依次是:system > const > eq_ref > ref > range > index > ALL。
    • system:系统表,少量数据,往往不需要进行磁盘IO
    • const:常量连接
    • eq_ref:主键索引(primary key)或者非空唯一索引(unique not null)等值扫描
    • ref:非主键非唯一索引等值扫描
    • range:范围扫描
    • index:索引树扫描
    • ALL:全表扫描(full table scan)
    • 执行计划possible_keys
      查询过程中有可能用到的索引

    • 执行计划key
      实际使用的索引,如果为NULL,则没有使用索引

    • 执行计划rows
      根据表统计信息或者索引选用情况,大致估算出找到所需的记录所需读取的行数

    • 执行计划filtered
      表示返回的行数需读取行数的百分比,filtered的值越大越好.

    • 执行计划Extra
      额外信息

    • Using filesort:MySQL 对数据使用一个外部的文件内容进行了排序,而不是按照表内的索引进行排序读取。
    • Using temporary:使用临时表保存中间结果,也就是说 MySQL 在对查询结果排序时使用了临时表,常见于order by 或 group by。
    • Using index:表示 SQL 操作中使用了覆盖索引(Covering Index),避免了访问表的数据行,效率高。
    • Using index condition:表示 SQL 操作命中了索引,但不是所有的列数据都在索引树上,还需要访问实际的行记录。
    • Using where:表示 SQL 操作使用了 where 过滤条件。
    • Select tables optimized away:基于索引优化 MIN/MAX 操作或者 MyISAM 存储引擎优化 COUNT(*) 操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即可完成优化。
    • Using join buffer(Block Nested Loop):表示 SQL 操作使用了关联查询或者子查询,且需要进行嵌套循环计算。

    五、慢查询日志

    MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10S以上的语句。默认情况下,MySQLl数据库并不启动慢查询日志,需要我们手动来设置这个参数,当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。

    • 查看是否开启慢查询功能
    show variables like 'slow_query%';
    # slow_query_log 慢查询开启状态
    # slow_query_log_file 慢查询日志存放的位置(这个目录需要MySQL的运行帐号的可写权限,一般设置为MySQL的数据存放目录)
    
    

    show variables like 'long_query_time';
    # long_query_time 查询超过多少秒才记录
    

    • 开启慢查询
      临时开启
    set global show_query_log='ON';
    set global slow_query_log_file='/usr/local/var/mysql/192-slow.log';
    set global long_query_time=2;
    

    永久开启,需要修改配置文件(mysql.cnf)

    [mysqld]
    slow_query_log = ON
    slow_query_log_file = /usr/local/var/mysql/192-slow.log
    long_query_time = 2
    

    END

  • 相关阅读:
    【LeetCode】150.逆波兰表达式(栈+数组 两种方法,java实现)
    【LeetCode】494. 目标和(枚举,动规,背包三种方法,java实现)
    【LeetCode】137.克隆图(dfs+bfs,java实现)
    java 面向对象(十二):面向对象的特征二:继承性 (一) 前言
    链表常用操作
    回溯法—八皇后问题
    回溯法—实例
    回溯法—子集树与排列树
    使用sklearn进行集成学习——实践
    使用sklearn进行集成学习——理论
  • 原文地址:https://www.cnblogs.com/hziwei/p/13565505.html
Copyright © 2020-2023  润新知