我的问题如下:
我有一个包含 23百万行的表mailmessage(1年的数据)。
以下是此表的重要字段
我在这张桌子上有一个全文索引:
CREATE FULLTEXT INDEX mailmessage_fulltext ON mailmessage (body,subject)
我需要在msgtimeutc上执行请求在正文和主题中搜索文字并按日期时间缩小,如下所示:
SELECT M.some_data
FROM mailmessage M
WHERE M.MSGTIMEUTC >= 1343651965 AND M.MSGTIMEUTC <= 1344170365
AND ( MATCH (M.BODY,M.SUBJECT) AGAINST ('test'));
mySQL
因此查询占用的时间太长(和I / O)!
我想要像这样做一个 intersect (示例代码没有经过测试)
SELECT M1.some_data FROM mailmessage M1
WHERE M1.MSGTIMEUTC >= 1343651965 AND M1.MSGTIMEUTC <= 1344170365
INTERSECT
SELECT M2.some_data FROM mailmessage M2
WHERE ( MATCH (M2.BODY,M2.SUBJECT) AGAINST ('test'));
解释(抱歉滚动条):
+----+-------------+-------+----------+---------------------------------+----------------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+----------+---------------------------------+----------------------+---------+------+------+-------------+
| 1 | SIMPLE | M | fulltext | msgtimeutc,mailmessage_fulltext | mailmessage_fulltext | 0 | | 1 | Using where |
+----+-------------+-------+----------+---------------------------------+----------------------+---------+------+------+-------------+
但它在mySQL上不存在
其他请求(如下面的2)也在进行全表扫描
SELECT M.some_data
FROM mailmessage M
WHERE
M.id in (
select m2.id from mailmessage m2 use index(mailmessage_fulltext)
where (MATCH (m2.BODY,m2.SUBJECT) AGAINST ('test'))
)
AND M.MSGTIMEUTC >= 1343651965 AND M.MSGTIMEUTC <= 1344170365;
或
SELECT M1.ATTACHMENTCOUNT AS ATCH_COUNT
FROM mailmessage AS M1
INNER JOIN mailmessage AS M2 ON M1.id = M2.id
WHERE (M1.MSGTIMEUTC >= 1343651965 AND M1.MSGTIMEUTC <= 1344170365)
AND (MATCH (M2.BODY,M2.SUBJECT) AGAINST ('test'))
两个查询解释计划只显示我使用的一个索引(全文)
所以我可能最终按日期过滤programmaticaly行...但我更喜欢(关于卷)数据库解决方案
有什么想法吗?
答案 0 :(得分:1)
从最新的MySQL版本开始,无法将全文索引与另一个
组合在一起http://dev.mysql.com/doc/refman/5.6/en/index-merge-optimization.html
索引合并不适用于全文索引。我们计划在未来的MySQL版本中扩展它以涵盖这些内容。
您可以尝试使用临时表解决您的问题:
CREATE TEMPORARY TABLE my_search
(FULLTEXT INDEX mailmessage_fulltext(body,subject))
SELECT M.some_data
FROM mailmessage M
WHERE M.MSGTIMEUTC >= 1343651965 AND M.MSGTIMEUTC <= 1344170365
然后将其与查询匹配
SELECT M.some_data
FROM my_search M
WHERE ( MATCH (M.BODY,M.SUBJECT) AGAINST ('test'));
请记住,对于此解决方案,实际表中的全文索引变得完全没用。