#建立表格 CREATE TABLE if not exists `article`( `id` int(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, `author_id` INT(10) UNSIGNED NOT NULL, `category_id` INT(10) UNSIGNED NOT NULL, `views` INT(10) UNSIGNED NOT NULL, `comments` INT(10) UNSIGNED NOT NULL, `title` VARBINARY(255) NOT NULL, `content` TEXT NOT NULL ); #插入数据 INSERT INTO `article`(`author_id`,`category_id`,`views`,`comments`,`title`,`content`) VALUES (1,1,1,1,'1','1'), (2,2,2,2,'2','2'), (1,1,3,3,'3','3');
#查询category_id为1且comments大于1的状况下,views最多的article_id SELECT id,author_id FROM article WHERE category_id=1 AND comments>1 ORDER BY views DESC LIMIT 1; #性能分析 explain SELECT id,author_id FROM article WHERE category_id=1 AND comments>1 ORDER BY views DESC LIMIT 1;
结论:type是ALL,Extra里面还出现了Using filesort,虽然这条语句可以查询出来结果,可是很消耗行性能,须要优化。mysql
(1)查看索引sql
show index from article;
(2)开始优化性能
方式一:新建索引+删除索引优化
建立索引spa
create index idx_article_ccv on article(`category_id`,`comments`,`views`);
删除索引code
drop index idx_article_ccv on article
这里咱们已经创建了索引,为何没有用?blog
这是由于按照BTree的工做原理,首先排序category_id,若是遇到相同的category_id,则在排序comments,若是遇到相同的comments,则再排序view。当comments字段在联合索引中处于中间位置时,由于comments>1条件是一个范围值(所谓range),MySQL没法利用索引再对后面的views部分进行检索,即range类型查询字段后面的索引无效。排序
方式二(正确)索引
create index idx_article_cv on article(category_id,views);