我在使用MySQL进行组查询时遇到了一些问题。
题
为什么查询不会在varchar(255)字段上使用10个字符的部分索引来优化组?
细节
我的设置:
CREATE TABLE `sessions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`ref_source` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`guid` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`initial_path` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`referrer_host` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`campaign` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_sessions_on_user_id` (`user_id`),
KEY `index_sessions_on_referrer_host` (`referrer_host`(10)),
KEY `index_sessions_on_initial_path` (`initial_path`(10)),
KEY `index_sessions_on_campaign` (`campaign`(10))
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci这里没有显示许多列和索引,因为它们不会真正影响问题。
我想要做的是运行一个查询来查看所有引用主机以及来自每个主机的会话数量。我没有一个巨大的桌子,但它足够大,我的桌上扫描没有乐趣。我想要运行的查询是:
SELECT COUNT(*) AS count_all, referrer_host AS referrer_host FROM `sessions` GROUP BY referrer_host;解释给出:
+----+-------------+----------+------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+--------+---------------------------------+
| 1 | SIMPLE | sessions | ALL | NULL | NULL | NULL | NULL | 303049 | Using temporary; Using filesort |
+----+-------------+----------+------+---------------+------+---------+------+--------+---------------------------------+我在referrer_host上有一个部分索引,但它没有使用它。即使我尝试USE INDEX或FORCE INDEX,也无济于事。解释和表现一样。
如果我在referrer_host上添加完整索引,而不是10个字符的部分索引,则即使不是即时,一切都会更好。 (350毫秒对比10秒)
我已经测试了比现场最长条目更大的部分索引,但无济于事。完整的索引是似乎工作的唯一的东西。