我的问题如下:
我有一个包含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'))
两个查询都解释了计划显示我只使用了一个索引(全文)
所以我最终可能会按日期过滤程序行......但我更喜欢(关于数量)数据库解决方案
任何的想法 ?