我有两张桌子:
CREATE TABLE `linf` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`glorious` bit(1) DEFAULT NULL,
`limad` varchar(127) COLLATE utf8_bin DEFAULT NULL,
`linfDetails_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `FK242415D3B0D13C` (`linfDetails_id`),
CONSTRAINT `FK242415D3B0D13C` FOREIGN KEY (`linfDetails_id`) REFERENCES `linfdetails` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=135111 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
(130K 行)
和
CREATE TABLE `messageentry` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`mboxOffset` bigint(20) DEFAULT NULL,
`mboxOffsetEnd` bigint(20) DEFAULT NULL,
`from_id` bigint(20) DEFAULT NULL,
`linf_ID` bigint(20) DEFAULT NULL,
`mailSourceFile_id` bigint(20) DEFAULT NULL,
`messageDetails_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKBBB258CB60B94D38` (`mailSourceFile_id`),
KEY `FKBBB258CB11F9E114` (`from_id`),
KEY `FKBBB258CBF7C835B8` (`messageDetails_id`),
KEY `FKBBB258CBB10E8518` (`linf_ID`),
CONSTRAINT `FKBBB258CBB10E8518` FOREIGN KEY (`linf_ID`) REFERENCES `linf` (`ID`),
CONSTRAINT `FKBBB258CB11F9E114` FOREIGN KEY (`from_id`) REFERENCES `emailandname` (`id`),
CONSTRAINT `FKBBB258CB60B94D38` FOREIGN KEY (`mailSourceFile_id`) REFERENCES `mailsourcefile` (`id`),
CONSTRAINT `FKBBB258CBF7C835B8` FOREIGN KEY (`messageDetails_id`) REFERENCES `messagedetails` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5888892 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
(5M 行)
我需要通过 linf.limad 找到 linf,然后找到这个 linf 对应的所有消息。
如果我在两个查询中选择它:
select sql_no_cache l.id from linf l where l.limad='test@';
select sql_no_cache me.* from messageentry me where me.linf_id = 118668;
然后需要 0.06 秒。
如果我使用
select sql_no_cache me.* from messageentry me where me.linf_id in(
select l.id from linf l where l.limad='test@') ;
执行需要 10 秒。和这个:
select sql_no_cache me.* from messageentry me, linf l where me.linf_id=l.id
and l.limad='test@';
需要 4 秒。(时间稳定)
此请求返回 0 个结果,因为没有此 linf 的消息。事实上,我已经从大请求中去掉了这个
select messageent1_.*
from
MailSourceFile mailsource0_,
MessageEntry messageent1_ ,
MessageDetails messagedet2_,
Linf linf3_
where
messageent1_.messageDetails_id = messagedet2_.id
and messageent1_.linf_ID = linf3_.ID
and linf3_.limad = 'test@'
and mailsource0_.id = messageent1_.mailSourceFile_id
这工作〜1分钟。这不是太多了吗?解释说没有使用 messageEntries 索引:
mysql> explain select sql_no_cache me.* from messageentry me, linf l where me.linf_id=l.id and l.limad='test@';
+----+-------------+-------+--------+--------------------+---------+---------+------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------+---------+---------+------------------+---------+-------------+
| 1 | SIMPLE | me | ALL | FKBBB258CBB10E8518 | NULL | NULL | NULL | 5836332 | |
| 1 | SIMPLE | l | eq_ref | PRIMARY | PRIMARY | 8 | skryb.me.linf_ID | 1 | Using where |
+----+-------------+-------+--------+--------------------+---------+---------+------------------+---------+-------------+
任何想法为什么?我已经获得了 mysql ~1.6 G 的内存,这应该适合所有表。
谢谢。