【发布时间】:2017-10-20 10:23:00
【问题描述】:
我有两张表来制作我的搜索引擎,一张包含所有关键字,另一张包含每个关键字的所有可能目标。
Table: keywords
id (int)
keyword (varchar)
Table: results
id (int)
keyword_id (int)
table_id (int)
target_id (int)
对于这两个表,我将 MyISAM 设置为存储引擎,因为 95% 的时间我只是在这些表上运行选择查询,而在 5% 的时间里,插入查询。当然,我已经比较了使用 InnoDB 的性能,考虑到我后来的查询,性能很差。
我还添加了以下索引
keywords.keyword (unique)
results.keyword_id (index)
results.table_id (index)
results.target_id (index)
在 keywords 表中,我有大约 120 万条记录,在 results 表中我有大约 980 万条记录。
现在问题是我运行以下查询,结果在 0.0014 秒内生成
SELECT rs.table_id, rs.target_id
FROM keywords ky INNER JOIN results rs ON ky.id=rs.keyword_id
WHERE ky.keyword LIKE "x%" OR ky.keyword LIKE "y%"
但是当我添加 GROUP BY 时,结果是在 0.2 秒内产生的
SELECT rs.table_id, rs.target_id
FROM keywords ky INNER JOIN results rs ON ky.id=rs.keyword_id
WHERE ky.keyword LIKE "x%" OR ky.keyword LIKE "y%"
GROUP BY rs.table_id, rs.target_id
我测试了复合索引、单列索引,甚至删除了 table_id 和 target_id 索引,但在所有情况下,性能都是一样的,似乎在 Group By 子句中,索引没有被应用。
解释计划表明:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | ky | range | PRIMARY,keyword | keyword | 767 | NULL | 3271 | Using index condition; Using where; Using temporary; Using filesort
1 | SIMPLE | rs | ref | keyword_id | keyword_id | 4 | ky.id | 3
我已经添加了以下复合键
ALTER TABLE results ADD INDEX `table_id` (`table_id`, `target_id`) USING BTREE;
【问题讨论】:
-
当服务器配置正确时,InnoDB 比 MyISAM 更快读取percona.com/blog/2007/01/08/…
-
我阅读了文档,我找不到任何关于服务器配置的信息,根据我的理解,考虑到我的应用程序,MyISAM 更快。
-
在 MyISAM 中,
keywords.keyword (unique)是次优的;使用 InnoDB 就可以了。
标签: mysql search group-by myisam large-data