单表查询如何建立索引让你的查询语句性能达到最高

  在我的上一篇博客<<Explain检测SQL语句的性能>>中简单的介绍了explain关键字查询结果字段.这篇博客将介绍如何用正确使用索引提高查询效率.

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

先来创建一张表:

[sql]  view plain  copy
  1. CREATE TABLE IF NOT EXISTS `article` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  2. `author_id` int(10) unsigned NOT NULL,  
  3. `category_id` int(10) unsigned NOT NULL,  
  4. `views` int(10) unsigned NOT NULL,  
  5. `comments` int(10) unsigned NOT NULL,  
  6. `title` varbinary(255) NOT NULL,  
  7. `content` text NOT NULL,  
  8. PRIMARY KEY (`id`)  
  9. );  

使用sql语句插入12条数据:

[sql]  view plain  copy
  1. INSERT INTO `article`  
  2. (`author_id`, `category_id`, `views`, `comments`, `title`, `content`) VALUES  
  3. (1, 1, 1, 1, '1''1'),  
  4. (2, 2, 2, 2, '2''2'),  
  5. (1, 1, 3, 3, '3''3'),  
  6. (4, 4, 4, 4, '4''4'),  
  7. (5, 5, 5, 5, '5''5'),  
  8. (4, 4, 6, 6, '6''6'),  
  9. (7, 7, 7, 7, '7''7'),  
  10. (8, 8, 8, 8, '8''8'),  
  11. (7, 7, 9, 9, '9''9'),  
  12. (1, 1, 1, 1, '1''1'),  
  13. (2, 2, 2, 2, '2''2'),  
  14. (1, 1, 3, 3, '3''3');  

测试:

查询 category_id 4 comments大于4的情况下,views最多的 article_id

执行查询语句:

扫描二维码关注公众号,回复: 57520 查看本文章

[sql]  view plain  copy
  1. SELECT *  
  2. FROM `article`  
  3. WHERE category_id =4 AND comments >4  
  4. ORDER BY views DESC  


查询时间

    看到这个时间的时候是不是感觉挺快的.那么再用explain看看这条语句的性能:

[sql]  view plain  copy
  1. EXPLAIN  
  2. SELECT *  
  3. FROM `article`  
  4. WHERE category_id = 4 AND comments >4  
  5. ORDER BY views DESC  

    看到这个结果,typeall ,是最坏的情况,就需要进行优化了.最简单的方法就是添加索引,但是索引应该怎么添加呢?我们来看看:

    查询条件之后共用了category_id,comments,views三个字段,那么就添加一个联合索引试试.

sql语句:

[sql]  view plain  copy
  1. ALTER TABLE `article` ADD INDEX x ( `category_id` , `comments`, `views` );  

添加的索引:


看看执行语句所需要的时间:



我们再看看sql的性能:


type类型已经是range,但是情况还是很糟糕.

在表中已经建立了索引,但是效果为什么这么差呢?回头看看建立的索引方法,可以看到索引方法是B-Tree.B-Tree索引的工作原理:先排序category_id,如果遇到相同的category_id则再排序comments,如果遇到相同的comments则再排序views.comments字段在联合索引里处于中间位置时,comments>1条件是一个范围值,mysql无法再索引在对后面的views部分进行检索.现在我们需要抛弃comments,

先删除旧索引,再建立新索引:

[sql]  view plain  copy
  1. DROP INDEX x ON article;  
  2. ALTER TABLE `article` ADD INDEX y ( `category_id` , `views` ) ;  

索引结果:

看看执行查询语句所需要时间:


再来看看sql语句的性能:


    从结果中,我们可以看出type的类型是ref,结果是比较理想的.而且extra中的using filesort也消失了.


    从整个过程中我们可以看出在小数据量的时候,从执行时间很难知道sql语句的性能如何,但是用explain关键字就可以检测出你的sql语句性能.从而我们也知道了添加索引的原则:

1.在作为查询条件的字段上添加索引,即跟在where后面的字段.

2.索引最好不要添加在查询条件为某个范围的字段上.

猜你喜欢

转载自blog.csdn.net/xiaoxiaoniaoQ/article/details/80064992