mysql增加索引的3条原则

一,索引的重要性

  索引用于快速找出在某个列中有一特定值的行。不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行。表越大,花费的时间越多。如果表中查询的列有一个索引,MySQL能快速到达一个位置去搜寻到数据文件的中间,没有必要看所有数据。注意如果你需要访问大部分行,顺序读取要快得多,因为此时我们避免磁盘搜索。

  假如你用新华字典来查找“张”这个汉字,不使用目录的话,你可能要从新华字典的第一页找到最后一页,可能要花二个小时。字典越厚呢,你花的时间就越多。现在你使用目录来查找“张”这个汉字,张的首字母是z,z开头的汉字从900多页开始,有了这条线索,你查找一个汉字可能只要一分钟,由此可见索引的重要性。但是索引建的是不是越多越好呢,当然不是,如果一本书的目录分成好几级的话,我想你也会晕的。

  二,准备工作

//准备二张测试表     mysql> CREATE TABLE `test_t` (      ->   `id` int(11) NOT NULL auto_increment,      ->   `num` int(11) NOT NULL default '0',      ->   `d_num` varchar(30) NOT NULL default '0',      ->   PRIMARY KEY  (`id`)      -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;     Query OK, 0 rows affected (0.05 sec)         mysql> CREATE TABLE `test_test` (      ->   `id` int(11) NOT NULL auto_increment,      ->   `num` int(11) NOT NULL default '0',      ->   PRIMARY KEY  (`id`)      -> ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;     Query OK, 0 rows affected (0.05 sec)           //创建一个存储过程,为插数据方便     mysql> delimiter |     mysql> create procedure i_test(pa int(11),tab varchar(30))      -> begin      ->     declare max_num int(11) default 100000;      ->     declare i int default 0;      ->     declare rand_num int;      ->  declare double_num char;      ->      ->  if tab != 'test_test' then      ->         select count(id) into max_num from test_t;      ->         while i < pa do     ->             if max_num < 100000 then      ->                 select cast(rand()*100 as unsigned) into rand_num;      ->                 select concat(rand_num,rand_num) into double_num;      ->                 insert into test_t(num,d_num)values(rand_num,double_num);      ->             end if;      ->             set i = i +1;      ->         end while;      ->  else     ->         select count(id) into max_num from test_test;      ->         while i < pa do     ->             if max_num < 100000 then      ->                 select cast(rand()*100 as unsigned) into rand_num;      ->                 insert into test_test(num)values(rand_num);      ->             end if;      ->             set i = i +1;      ->         end while;      ->  end if;      -> end|     Query OK, 0 rows affected (0.00 sec)         mysql> delimiter ;     mysql> show variables like "%pro%";   //查看一下,记录执行的profiling是不是开启动了,默认是不开启的     +---------------------------+-------+     | Variable_name             | Value |     +---------------------------+-------+     | profiling                 | OFF   |     | profiling_history_size    | 15    |     | protocol_version          | 10    |     | slave_compressed_protocol | OFF   |     +---------------------------+-------+     4 rows in set (0.00 sec)           mysql> set profiling=1;           //开启后,是为了对比加了索引后的执行时间     Query OK, 0 rows affected (0.00 sec)  

  三,实例

  1,单表数据太少,索引反而会影响速度

mysql> call i_test(10,'test_t');    //向test_t表插入10条件     Query OK, 1 row affected (0.02 sec)         mysql> select num from test_t where num!=0;     mysql> explain select num from test_t where num!=0G;     *************************** 1. row ***************************      id: 1      select_type: SIMPLE      table: test_t      type: ALL      possible_keys: NULL      key: NULL      key_len: NULL      ref: NULL      rows: 10      Extra: Using where     1 row in set (0.00 sec)         ERROR:     No query specified         mysql> create index num_2 on test_t (num);     Query OK, 10 rows affected (0.19 sec)     Records: 10  Duplicates: 0  Warnings: 0         mysql> select num from test_t where num!=0;         mysql> explain select num from test_t where num!=0G;     *************************** 1. row ***************************      id: 1      select_type: SIMPLE      table: test_t      type: index      possible_keys: num_2      key: num_2      key_len: 4      ref: NULL      rows: 10      Extra: Using where; Using index     1 row in set (0.00 sec)         ERROR:     No query specified         mysql> show profiles;     +----------+------------+---------------------------------------------+     | Query_ID | Duration   | Query                                       |     +----------+------------+---------------------------------------------+     |        1 | 0.00286325 | call i_test(10,'test_t')                    |    //插入十条数据     |        2 | 0.00026350 | select num from test_t where num!=0         |     |        3 | 0.00022250 | explain select num from test_t where num!=0 |     |        4 | 0.18385400 | create index num_2 on test_t (num)          |    //创建索引     |        5 | 0.00127525 | select num from test_t where num!=0         |    //使用索引后,差不多是没有使用索引的0.2倍     |        6 | 0.00024375 | explain select num from test_t where num!=0 |     +----------+------------+---------------------------------------------+     6 rows in set (0.00 sec)   

  解释:

  id:表示sql执行的顺序

  select_type:SIMPLE,PRIMARY,UNION,DEPENDENT UNION,UNION RESULT,SUBQUERY,DEPENDENT SUBQUERY,DERIVED不同的查询语句会有不同的select_type

  table:表示查找的表名

  type:表示使用索引类型,或者有无使用索引.效率从高到低const、eq_reg、ref、range、index和ALL,其实这个根你sql的写法有直接关系,例如:能用主键就用主键,where后面的条件加上索引,如果是唯一加上唯一索引等

  possible_keys:可能存在的索引

  key:使用索引

  key_len:使用索引的长度

  ref:使用哪个列或常数与key一起从表中选择行,一般在多表联合查询时会有。

  rows:查找出的行数

  Extra:额外说明

  前段时间写过一篇博文mysql distinct和group by谁更好,里面有朋友留言,说测试结果根我当时做的测试结果不一样,当时我打比方解释了一下,今天有时间,以例子的形势,更直观的表达出索引的工作原理。

  2,where后的条件,order by ,group by 等这样过滤时,后面的字段最好加上索引。根据实际情况,选择PRIMARY KEY、UNIQUE、INDEX等索引,但是不是越多越好,要适度。

  3,联合查询,子查询等多表操作时关连字段要加索引

mysql> call i_test(10,'test_test');    //向test_test表插入10条数据     Query OK, 1 row affected (0.02 sec)         mysql> explain select a.num as num1,b.num as num2 from test_t as a left join tes     t_test as b on a.num=b.numG;     *************************** 1. row ***************************      id: 1      select_type: SIMPLE      table: a      type: index      possible_keys: NULL      key: num_2      key_len: 4      ref: NULL      rows: 10      Extra: Using index     *************************** 2. row ***************************      id: 1      select_type: SIMPLE      table: b      type: ref      possible_keys: num_1      key: num_1      key_len: 4      ref: bak_test.a.num   //bak_test是数据库名,a.num是test_t的一个字段      rows: 1080      Extra: Using index     2 rows in set (0.01 sec)         ERROR:     No query specified   

  数据量特别大的时候,最好不要用联合查询,即使你做了索引。

  上面只是个人的一点小结,抛砖引玉一下。

时间: 2024-11-09 00:18:51

mysql增加索引的3条原则的相关文章

添加mysql索引的3条原则

一,索引的重要性 索引用于快速找出在某个列中有一特定值的行.不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行.表越大,花费的时间越多.如果表中查询的列有一个索引,MySQL能快速到达一个位置去搜寻到数据文件的中间,没有必要看所有数据.注意如果你需要访问大部分行,顺序读取要快得多,因为此时我们避免磁盘搜索. 假如你用新华字典来查找"张"这个汉字,不使用目录的话,你可能要从新华字典的第一页找到最后一页,可能要花二个小时.字典越厚呢,你花的时间就越多.现在你使用目录来

mysql索引合并:一条sql可以使用多个索引

前言 mysql的索引合并并不是什么新特性.早在mysql5.0版本就已经实现.之所以还写这篇博文,是因为好多人还一直保留着一条sql语句只能使用一个索引的错误观念.本文会通过一些示例来说明如何使用索引合并. 什么是索引合并 下面我们看下mysql文档中对索引合并的说明: The Index Merge method is used to retrieve rows with several range scans and to merge their results into one. The

MySql 创建索引原则

为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引.本小节将向读者介绍一些索引的设计原则.   1.选择唯一性索引   唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录.例如,学生表中学号是具有唯一性的字段.为该字段建立唯一性索引可以很快的确定某个学生的信息.如果使用姓名的话,可能存在同名现象,从而降低查询速度.   2.为经常需要排序.分组和联合操作的字段建立索引   经常需要ORDER BY.GROUP BY.DISTINCT和UNION等操

mysql联合索引

命名规则:表名_字段名1.需要加索引的字段,要在where条件中2.数据量少的字段不需要加索引3.如果where条件中是OR关系,加索引不起作用4.符合最左原则 https://segmentfault.com/q/1010000003984016/a-1020000003984281 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c

MySQL 创建索引、修改索引、删除索引的命令语句

mysql创建索引.修改索引.删除索引的命令语句 查看表中已经存在 index: show index from table_name; 创建和删除索引:索引的创建可以在 CREATE TABLE 语句中进行,也可以单独用 CREATE INDEX 或 ALTER TABLE 来给表增加索引.删除索引可以利用ALTER TABLE 或 DROP INDEX 语句来实现. PS: MySQL创建索引原则 http://blog.csdn.net/csdnones/article/details/5

Mysql使用索引实现查询优化_Mysql

索引的目的在于提高查询效率,可以类比字典,如果要查"mysql"这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql.如果没有索引,那么你可能需要把所有单词看一遍才能找到你想要的. 1.索引的优点 假设你拥有三个未索引的表t1.t2和t3,每个表都分别包含数据列i1.i2和i3,并且每个表都包含了1000条数据行,其序号从1到1000.查找某些值匹配的数据行组合的查询可能如下所示: SELECT t1.i1, t2.i2, t3.i3 FROM t1, t2,

mysql 复合索引,前后顺序

问题描述 mysql 复合索引,前后顺序 表用来保存设备传送来的采集信息 设备暂定10000台,日后会继续增加,每5S传送一个采集信息,一个月度表,千万条记 问题: 设备Id和采集时间在索引中的先后顺序,应该哪个在前哪个在后, 解决方案 mysql中复合索引 解决方案二: 可以用设备id在前面 时间在后面的方式复合索引

(转)精益技术简历之道——改善技术简历的47条原则

作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://lucida.me/blog/lean-technical-resume/ 关于 这篇文章围绕着技术简历这个话题,从版式.个人信息.技术能力.项目经历和教育背景等方面出发,给出了编写高质量技术简历所应遵循的47条原则.它们既有益于求职者编写高质量的简历,也有助于招聘者筛选合格的求职者. 为什么要编写这篇文章? 技术简历既是技术人员求职必不可少的一环,也是找工作的第一步,其重要性不言而喻.然而关于如何编

简单介绍下MYSQL的索引类型_Mysql

一.介绍一下索引的类型 Mysql常见索引有:主键索引.唯一索引.普通索引.全文索引.组合索引 PRIMARY KEY(主键索引) ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) UNIQUE(唯一索引) ALTER TABLE `table_name` ADD UNIQUE (`column`) INDEX(普通索引)      ALTER TABLE `table_name` ADD INDEX index_name ( `colu