我有以下查询来获取上个月提交的观看次数最多的文章。
explain
SELECT *
FROM article
WHERE date > 1315391769
ORDER BY views DESC
LIMIT 10
如何为此查询选择正确的索引?或者如何重新编写它以避免扫描大量行或文件排序?
这是我尝试过的当前索引的表格方案:
CREATE TABLE `article` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(50) NOT NULL,
`body` text NOT NULL,
`date` int(32) NOT NULL,
`views` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `date` (`date`),
KEY `views` (`views`),
KEY `date_2` (`date`,`views`),
KEY `views_2` (`views`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=200003 ;
--
-- Dumping data for table `article`
--
INSERT INTO `article` VALUES (1, 'title test113', 'test body118', 1317912183, 5017);
INSERT INTO `article` VALUES (2, 'title test193', 'test body193', 1313441124, 5943);
INSERT INTO `article` VALUES (3, 'title test112', 'test body116', 1312773586, 653);
INSERT INTO `article` VALUES (4, 'title test378', 'test body374', 1316786646, 4589);
INSERT INTO `article` VALUES (5, 'title test335', 'test body3310', 1319173694, 6224);
注意:我也尝试过mysql而不是Unix时间戳,但我得到了相同的结果。
这是EXPLAIN的输出:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE article range date,date_2 date 4 NULL 107245 Using where; Using filesort
答案 0 :(得分:1)
单个密钥date_2
(date
,views
)应该为相关查询提供最佳性能。请参阅here我不认为其他索引会有所帮助。由于查询非常简单,我无法想到任何其他优化!
答案 1 :(得分:1)
对于此类查询,只能使用(date)
或(views)
索引,而不能使用复合(date,views)
。 MySQL选择使用的可能是也可能不是最佳的。 2月的最佳数据可能不适用于4月的数据!
您可以尝试强制执行其中之一并测量性能。
您可以使用Year-Month
{2011年4月CHAR(6)
添加201104
数据的计算列(该列可以使用INSERT和UPDATE触发器更新)或者int
24136
,如WHERE YearMonth = '201109' --- for September
(24136 = 2011 * 12 + 4)。
然后你的情况会是:
WHERE YearMonth = 2011*12+9
或
(YearMonth, views)
可以使用{{1}}索引。
答案 2 :(得分:1)
通过强制索引,可以实现。
explain
SELECT *
FROM article force index (`views`)
WHERE date>=1315391768
ORDER BY views DESC
LIMIT 10
解释计划:
"id" "select_type" "table" "type" "possible_keys" "key" "key_len" "ref" "rows" "Extra"
"1" "SIMPLE" "article" "index" \N "views" "4" \N "5" "Using where"