索引的建立及优化-单表分析
1.单表优化
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for article
-- ----------------------------
DROP TABLE IF EXISTS `article`;
CREATE TABLE `article` (
`id` int(10) NOT NULL,
`author_id` int(10) NOT NULL,
`category_id` int(10) NOT NULL,
`views` int(10) NOT NULL,
`comments` int(10) NOT NULL,
`title` varbinary(255) NOT NULL,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of article
-- ----------------------------
INSERT INTO `article` VALUES (1, 1, 1, 1, 1, 0x31, '1');
INSERT INTO `article` VALUES (2, 2, 2, 2, 2, 0x32, '2');
INSERT INTO `article` VALUES (3, 1, 1, 3, 3, 0x33, '3');
SET FOREIGN_KEY_CHECKS = 1;
查询case
1.查询category_id为1且comments大于1的情况下,views最多的article_id
EXPLAIN SELECT id FROM article WHERE category_id=1 and comments >1 ORDER BY views DESC LIMIT 1
结论
type为ALL全表扫描,Extra中有Using filesort 文件排序 必须优化
优化
1.建立联合索引
CREATE INDEX index_article_ccv ON article(category_id,comments,views)
查询优化结果
EXPLAIN SELECT id FROM article WHERE category_id=1 and comments >1 ORDER BY views DESC LIMIT 1
解决了全表扫描的问题,但是没有解决Using filesort的问题,试试将comments>1 改为comments=1则
EXPLAIN SELECT id FROM article WHERE category_id= 1 and comments = 1 ORDER BY views DESC LIMIT 1
结论:
type变成range,这是可以忍受的。但是extra里使用Using filesort仍然无法接受的。但是我们已经建立了索引,为啥没用呢?
这是因为按照BTree索引的工作原理,先排序category_id,如果遇到相同的category_id,则再排序comments,如果遇到相同的comments则再排序views。
当comments字段在联合索引中处于中间位置时,因为comments>1条件是一个范围值(所谓range)
MySQL无法利用索引对后面的views部分进行检索,即range类型查询字段后面的索引无效
说明comments>1导致后面的索引没有用上,当前索引不合适 删除索引
DROP INDEX index_article_ccv ON article
查看查询
EXPLAIN SELECT id FROM article WHERE category_id= 1 and comments > 1 ORDER BY views DESC LIMIT 1
那我们建立索引去掉中间的comments字段直接category_id以及views字段建立联合索引
CREATE INDEX index_article_cv ON article(category_id,views)
查看索引
SHOW INDEX FROM article
查看查询
EXPLAIN SELECT id FROM article WHERE category_id=1 and comments > 1 ORDER BY views DESC LIMIT 1
结论
type也达到了更好的ref,同时filesort 文件排序也消失了,得到了较好的优化