zoukankan      html  css  js  c++  java
  • mysql优化——索引与索引优化

          说起提高数据库性能,索引是最物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行个正确的’create index’,查询速度就可能提高百倍千倍,这可真有诱惑力。可是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作,增加了大量的I/O。 

    MySQL的索引种类

    Mysql索引包含:普通索引、主键索引、唯一索引、全文索引,为了适应不同的查询、数据结构,提高查询速度,选择合适的索引方式。

    1.普通索引

    这是最基本的索引,它没有任何限制。

    普通索引的创建方式:

    一般来说,普通索引的创建,是先创建表,然后在创建普通索引,代码如下

    create table ccc(
    
    id int unsigned,
    
    name varchar(32)
    
    )
    
    create index ccc_index on ccc (id,name);

    修改表结构创建索引:

    ALTER mytable ADD INDEX [indexName] ON (username(length))

    创建表是指定索引:

    CREATE TABLE mytable( 
      ID INT NOT NULL,  
      username VARCHAR(16) NOT NULL,  
      INDEX [indexName] (username(length))   
    ); 

    删除索引:

    DROP INDEX [indexName] ON ccc;
    

    注:上述实例代码中的 length,如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。  

    2.主键索引

    主键没有着明确的概念定义,其是索引的一种,并且是唯一性索引的一种,且必须定义为“PRIMARY KEY”,主键不能重复,一个表只能有一个主键。

    主键字段,不能为NULL,也不能重复;一般是在建表的时候同时创建主键索引;

    当一张表,把某个列设为主键的时候,则该列就是主键索引。

    创建表时指定主键索引,实例

    create table aaa
    (id int unsigned primary key auto_increment ,
    name varchar(32) not null defaul ‘’);

    建表完成后创建索引:

    alter table 表名 add primary key (列名);

    3.全文索引

    全文索引,主要是针对对文件,文本的检索, 比如文章, 全文索引针对MyISAM有用.

    创建全文索引,实例:

    CREATE TABLE articles (
           id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
           title VARCHAR(200),
           body TEXT,
           FULLTEXT (title,body)
         )engine=myisam charset utf8;

    全文索引的使用方式,实例:match()  against()

    select * from articles where match(title,body) against(‘database’); 

    注:

    1. 在mysql中fulltext 索引只针对 myisam存储引擎生效;
    2. mysql自己提供的fulltext针对英文生效,对中文无效->sphinx (coreseek) 技术处理中文;
    3. 使用方法是 match(字段名..) against(‘关键字’);
    4. 全文索引一个 叫 停止词,  因为在一个文本中,创建索引是一个无穷大的数,因此,对一些常用词和字符,就不会创建,这些词,称为停止词。

    以下全文停止词部分展示,其他可以查阅MySQL手册

     4.唯一索引

    当表的某列被指定为unique约束时,这列就是一个唯一索引;

    unique字段可以为NULL,并可以有多个NULL, 但是如果是具体内容,则不能重复.

    创建表时声明唯一索引,实例:

    create table ddd(
    id int primary key auto_increment ,
    name varchar(32) unique);

    在创建表后,再去创建唯一索引,实例:

    create table eee(
    id int primary key auto_increment, 
    name varchar(32));
    
    create unique index eee_index  on eee(name);

    MySQL索引的sql操作

    1.查询索引

    show index[es] from tableName;
    #或者
    show keys from tableName;

    2.删除索引

    alter table tableName drop index indexName; 

    3.修改索引

    先删除,再重新创建.

    MySQL索引的的优点和不足

    不足:

    I.磁盘占用;

    例如MyISAM在磁盘上存储成3个文件,其中文件名和表名都相同,但是扩展名分别为:

    • .frm(存储表定义)
    • MYD(MYData,存储数据)
    • MYI(MYIndex,存储索引) 占用一定的磁盘空间,随着数据的增加索引文件也会增加
     
    II.对dml(update delete insert)语句的效率影响;
        数据的变化,需要同时维护索引

    优点:

    查询速度变快,但是为什么变快?

    简单理解:没有索引的情况,要进行全表查询,加上索引后利用BTree方式进行数据检索,要检索的数据量大大减少,索引检索速度要快的多。

    可以参考MySQL索引的实现方式,进行理解,参考文章

    http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html

    MySQL索引的应用

    适合索引的情况:

    • 肯定在where条经常使用
    • 该字段的内容不是唯一的几个值(sex)
    • 字段内容不是频繁变化.

    使用索引的注意事项:

    #实例说明:在dept表中创建符合索引
    # dname 左边的列,loc就是右边的列
    alter table dept add index my_ind (dname,loc); 

    说明,如果我们的表中有复合索引(索引作用在多列上), 此时我们注意:

    • 对于创建的多列索引,只要查询条件使用了最左边的列,索引一般才会被使用。
    explain select * from dept where loc='aaa'G  #就不会使用到索引

      #explain 可以帮助我们在不真正执行某个sql语句时,就执行mysql怎样执行,这样利用我们去分析sql指令.

    explain select * from dept where dname='aaa'G  #就会使用到索引
    • 如果条件中有or,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须建立索引, 我们建议大家尽量避免使用or 关键字;
    • select * from dept where dname=’xxx’ or loc=’xx’ or deptno=45
      #上述条件出现的条件字段必须建立索引
    • 对于使用like的查询,查询如果是  ‘%aaa’ 不会使用到索引,利用‘aaa%就可以’;
    • explain select * from dept where dname like '%aaa'G  
      #不能使用索引,即,在like查询时,关键的 ‘关键字’ , 最前面,不能使用 % 或者 _这样的字符., 如果一定要前面有变化的值,则考虑使用 全文索引->sphinx.
    • 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。(添加时,字符串必须’’),也就是,如果列是字符串类型,就一定要用 ‘’ 把他包括起来;
    • 如果mysql估计使用全表扫描要比使用索引快,则不使用索引。

     explain工具介绍

    explain 可以帮助我们在不真正执行某个sql语句时,就执行mysql怎样执行,这样利用我们去分析sql指令.

    •Possible_key :该查询可以利用的索引,如果没有任何索引可以使用null
    •Key                : Mysql 从 Possible_key 中所选择使用索引
    •Key_len         :被选中使用索引的索引长度
    •Rows             :显示MySQL认为它执行查询时必须检查的行数

    •extra   :查询细节信息

    No tables 

    Query语句中使用FROM DUAL 或不含任何FROM子句

    Using filesort 

    当Query中包含 ORDER BY 操作,而且无法利用索引完成排序,

    Impossible WHERE noticed after reading const tables: MYSQL Query Optimizer
    通过收集统计信息不可能存在结果
    Using temporary
    某些操作必须使用临时表,常见 GROUP BY  ; ORDER BY
    Using where
    不用读取表中所有信息,仅通过索引就可以获取所需数据;

     如何查看索引使用的情况

    show status like ‘Handler_read%’;

    大家可以注意:
    handler_read_key:这个值越高越好,越高表示使用索引查询到的次数。

    handler_read_rnd_next:这个值越高,说明查询低效。

    采菊东篱下,悠闲现南山~
  • 相关阅读:
    关于 python 库config 的相关介绍
    关于usr/bin/ld: cannot find -lxxx问题总结
    python中argparse模块
    剑指offer——二叉树中和为某一值的路径
    剑指Offer——整数中1出现的次数(从1到n整数中1出现的次数)
    python操作redis集群
    redis-cluster配置
    redis主从同步
    redis不重启,切换RDB备份到AOF备份
    redis持久化RDB与AOF
  • 原文地址:https://www.cnblogs.com/ChaosJu/p/4545078.html
Copyright © 2011-2022 走看看