Mysql数据库的优化技术-索引分类

Mysql的四种索引:

  • 主键索引
  • 唯一索引
  • 全文索引
  • 普通索引

1. 索引的添加

1.1 主键索引

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

create table aaa

(id int unsigned primary key auto_increment ,

name varchar(32) not null defaul ‘’);

这是id 列就是主键索引.

如果你创建表时,没有指定主键索引,也可以在创建表后,在添加, 指令:

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

举例:

create table bbb (id int , name varchar(32) not null default ‘’);

alter table bbb add primary key (id);

1.2 普通索引

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

比如:

create table ccc(

      id int unsigned,

     name varchar(32)

)

create index 索引名 on (1,列名2);

 1.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;

INSERT INTO articles (title,body) VALUES

     ('MySQL Tutorial','DBMS stands for DataBase ...'),

     ('How To Use MySQL Well','After you went through a ...'),

     ('Optimizing MySQL','In this tutorial we will show ...'),

     ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),

     ('MySQL vs. YourSQL','In the following database comparison ...'),

     ('MySQL Security','When configured properly, MySQL ...');

如何使用全文索引:

错误用法:

select * from articles where body like ‘%mysql%’; 【不会使用到全文索引】

证明:

explain  select * from articles where body like ‘%mysql%’

正确的用法是:

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

☞ 说明:

1. mysqlfulltext 索引只针对 myisam生效

2. mysql自己提供的fulltext针对英文生效->sphinx (coreseek) 技术处理中文

3. 使用方法是 match(字段名..) against(关键字’)

4. 全文索引一个 停止词,  因为在一个文本中,创建索引是一个无穷大的数,因此,对一些常用词和字符,就不会创建,这些词,称为停止词.

1.4唯一索引

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

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

这时, name 列就是一个唯一索引.

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

主键字段,不能为NULL,也不能重复.

②在创建表后,再去创建唯一索引

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

create unique index 索引名 on  表名 (列表..);


2. 查询索引

desc 表名 【该方法的缺点是: 不能够显示索引名.

show index(es) from 表名

show keys from 表名

3. 删除

alter table 表名 drop index 索引名;

如果删除主键索引。

alter table 表名 drop primary key       [这里有一个小问题]

4. 修改

先删除,再重新创建.


为什么加上索引会变得很快:


索引的注意事项:

索引的代价

  • 占用磁盘空间
  • 对ddl操作有影响,变慢
  • 在哪些列上适合添加索引

      1. 较频繁的作为查询条件字段应该创建索引

         select * from emp where empno = 1;

      2. 唯一性太差的字段不适合创建索引,即使频繁作为查询条件。

         select * from emp  where sex = '男';

     3. 更新频繁的字段不适合创建索引

        select * from emp where logincount = 1;

     4. 不会出现在where子句中字段不该创建索引

总结:满足一下条件的字段,才应该创建索引

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

 使用索引的注意事项

dept表中,我增加几个部门:

alter table dept add index my_ind (dname,loc); //  dname 左边的列,loc就是右边的列


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

1, 对于创建的多列索引,只要查询条件使用了最左边的列,索引一般就会被使用

explain select * from dept where loc='aaa'\G 

就不会使用到索引

2对于使用like的查询,查询如果是  ‘%aaa’ 不会使用到索引

aaa%’ 会使用到索引。

比如: explain select * from dept where dname like '%aaa'\G

不能使用索引,即,在like查询时,关键的 关键字’ , 最前面,不能使用 % 或者 _这样的字符., 如果一定要前面有变化的值,则考虑使用 全文索引->sphinx.

1. 如果条件中有or,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须建立索引, 我们建议大家尽量避免使用or 关键字

select * from dept where dname=’xxx’ or loc=’xx’ or deptno=45

2. 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。(添加时,字符串必须’’), 也就是,如果列是字符串类型,就一定要用 ‘’ 把他包括起来.

3. 如果mysql估计使用全表扫描要比使用索引快,则不使用索引。


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

常见sql的优化:

  • 大批量插入数据时,对于InnoDB,

       1.将要导入的数据按照主键排序

      2. set unique_checks = 0; 关闭唯一性校验

      3. set autocommit,关闭 自动提交

  •  优化group by 语句

      默认情况,MySQL对所有的group by col1,col2 进行排序。这与查询中指定order by col1,col2类似。如果查询中包括group by 但用户想要避免排序结果的消耗,则可以使用order by null 禁止排序。


  • 有些情况下,可以使用连接来替代子查询

       因为使用join,MySQL不需要在内存中创建临时表

select * from dept, emp where dept.deptno=emp.deptno; [简单处理方式]

select * from dept left join emp on dept.deptno=emp.deptno;  [左外连接,更ok!]
  •   如果想要在含有or的查询语句中利用索引,则or之间的每个条件都必须使用到索引,如果没有索引,则应该考虑增加索引
    select * from 表名 where 条件1=‘’ or 条件2 = '';

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

如何查看索引使用的情况:

show status like ‘Handler_read%’;

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

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

猜你喜欢

转载自blog.csdn.net/fd2025/article/details/80346322