4

我的问题如下:

我有一个包含2300 万行(1 年数据)的表邮件消息。
以下是该表的重要字段

  • id(大整数)
  • msgtimeutc (bigint)
  • 主题(小文本)
  • 主体)
  • 要显示的其他一些数据

我在这张桌子上有一个全文索引:
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

  • 不能同时使用 2 个索引(msgtimeutc 和 fulltextindex 上的一个)。所以我的查询结束了对 msgtimeutc 的全表扫描
  • 我不能在全文索引中包含 msgtimeutc,因为它是一个 bigint,我在上面或下面做

所以查询花费了太长时间(和 I/O)!

我坚持做这样的相交(示例代码未经测试)

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'))

两个查询都解释了计划显示我只使用了一个索引(全文)

所以我最终可能会按日期过滤程序行......但我更喜欢(关于数量)数据库解决方案

任何的想法 ?

4

1 回答 1

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'));

请记住,对于此解决方案,真实表中的全文索引变得完全无用。

于 2012-08-13T14:48:28.650 回答