【发布时间】:2011-08-01 02:10:36
【问题描述】:
我在使用 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 秒)
我已经测试了大于该字段中最长条目的部分索引也无济于事。完整索引是唯一可行的方法。
【问题讨论】:
-
你对“部分索引”的理解到底是什么?你能告诉我们 CREATE INDEX 语句吗?
-
@horse 我指的是仅包含字符串前 n 个字符的索引。索引创建在 table create 语句中。
KEY index_sessions_on_referrer_host (referrer_host(10))