我正在尝试优化MySQL表以便更快地读取。读写比例约为100:1,因此我倾向于牺牲多索引的写性能。
我的表的相关字段如下,它包含大约200000条记录
CREATE TABLE `publications` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
-- omitted fields
`publicaton_date` date NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '0',
`position` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
-- these are just attempts, they are not production index
KEY `publication_date` (`publication_date`),
KEY `publication_date_2` (`publication_date`,`position`,`active`)
) ENGINE=MyISAM;`enter code here`
由于我使用Ruby on Rails访问此表中的数据,因此我已为此表定义了一个默认范围
default_scope where(:active => true).order('publication_date DESC, position ASC')
即。默认情况下,此表中的每个查询都将使用以下SQL片段自动完成,因此您可以假设几乎所有查询都具有这些条件
WHERE `publications`.`active` = 1 ORDER BY publication_date DESC, position
所以我主要感兴趣的是优化这种查询,以及在WHERE条件下使用publication_date进行查询。
我尝试了以下各种组合的索引(同时也有多个组合)
`publication_date`
`publication_date`,`position`
`publication_date`,`position`,`active`
然而,一个简单的查询仍然没有正确使用索引并使用filesort
SELECT `publications`.* FROM `publications`
WHERE `publications`.`active` = 1
AND (id NOT IN (35217,35216,35215,35218))
ORDER BY publication_date DESC, position
LIMIT 8 OFFSET 0
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: publications
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 34903
Extra: Using where; Using filesort
1 row in set (0.00 sec)
关于我的问题的一些注意事项:
active
是一个布尔标志,所以把它放在一个独立的索引中没有意义(它只有2个可能的值)但是它总是在WHERE子句中使用,所以它应该出现在索引的某个地方以避免使用where在Extra position
是一个几乎没有可能值的整数,它始终用作publication_date
的范围,因此我认为将它放在独立索引中是没用的publication_date
,因此将它也放在独立索引中也很有用,即使是多余的,也是复合索引的第一列。答案 0 :(得分:0)
一个问题是您在order by子句中混合排序顺序。您可以反转您的位置(inverted_position = max_position - position),以便您也可以反转该列的排序顺序。
然后,您可以在 [publication_date,inverted_position] 上创建复合索引,并将order by子句更改为 publication_date DESC,inverted_position DESC 。
活动列很可能不属于索引的一部分,因为它的选择性非常低。