我试图优化一个涉及两个表的左连接,但是我无法让我的头绕着可能的索引加速事情。 表1包含2171289行:MySQL左加入分组 - 索引优化
text_metadata_for_nzcorpus | CREATE TABLE `text_metadata_for_nzcorpus` (
`text_id` varchar(255) NOT NULL,
`newspaper` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`year` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`month` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`day` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`section` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`subsection` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`topics` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`words` int(11) NOT NULL DEFAULT '0',
`cqp_begin` bigint(20) unsigned NOT NULL DEFAULT '0',
`cqp_end` bigint(20) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`text_id`),
KEY `newspaper` (`newspaper`),
KEY `year` (`year`),
KEY `month` (`month`),
KEY `day` (`day`),
KEY `section` (`section`),
KEY `subsection` (`subsection`),
KEY `topics` (`topics`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
第二个表只包含8584行:
db_dist_fb8ddyk760 | CREATE TABLE `db_dist_fb8ddyk760` (
`text_id` varchar(255) COLLATE utf8_bin DEFAULT NULL,
`beginPosition` int(11) DEFAULT NULL,
`endPosition` int(11) DEFAULT NULL,
`refnumber` mediumint(9) NOT NULL AUTO_INCREMENT,
KEY `refnumber` (`refnumber`),
KEY `text_id` (`text_id`)
) ENGINE=InnoDB AUTO_INCREMENT=16384 DEFAULT CHARSET=utf8 COLLATE=utf8_bin |
我需要运行以下类型的查询:
SELECT md.day as handle, count(db.text_id) as hits,
count(distinct db.text_id) as files FROM text_metadata_for_nzcorpus as md
LEFT JOIN db_dist_fb8ddyk760 as db on md.text_id = db.text_id
GROUP BY md.day;
目前这需要更多处理时间超过5秒。由于这是我在网页上显示输出之前需要运行的很多查询中的一种,如果可能的话,我希望加快速度。这里是“解释”的输出:
+----+-------------+-------+-------+---------------+---------+---------+----------------------+---------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+----------------------+---------+--------------------------+
| 1 | SIMPLE | md | index | day | day | 768 | NULL | 2452080 | Using index |
| 1 | SIMPLE | db | ref | text_id | text_id | 768 | cqpweb_db.md.text_id | 1 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+----------------------+---------+--------------------------+
任何有帮助的建议,将不胜感激。 (我不是系统的开发人员,我不负责代码本身 - 但如果事情可以改进,我想为程序员提供输入...)
非常感谢! Sebastian
感谢您的支持。不幸的是,text_id不能成为主键。将尝试你建议的其他事情。 –
因为它被缓存,并且可以在其他用户执行相同的查询时再次使用 - 这为创建这些数据库节省了相当多的时间。没有办法事先了解多久使用一次特定数据库的用户数量。有时30个人可能会做同样的事情(这就是为什么缓存有意义),有时用户可能会导致编译一个巨大的表仅仅看一次输出......我们已经选择了持久数据库选项,因为在整体来看,这似乎是最好的折衷方案。 –
另外,“日”不是我认为你认为它是... ;-)“日”只是一个句柄,可以包含文本集合中的任何级别的注释(在这种情况下,它确实是一天的月份,即1到31之间的数字)。所有这些涉及到电子文本语料库的接口 - http://cwb.sourceforge.net/cqpweb.php - 如果您有兴趣的话。 –