SELECT * FROM `threads` where `createbyid` <> 24016 AND `id` in (SELECT `threadid` FROM `thread_replys` WHERE `userid` = 24016 GROUP BY `threadid`);
这么一句sql,要想高效,应该怎么写?
试试用join: SELECT t.* FROM threads t inner join thread_replys r ON t.id = r.threadid where t.createbyid <> 24016 AND r.userid = 24016;
CREATE TABLE `threads` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL DEFAULT '',
`content` blob NOT NULL,
`createby` varchar(50) NOT NULL DEFAULT '',
`createbyid` int(11) NOT NULL,
`lastreply` varchar(50) NOT NULL DEFAULT '',
`lastreplyid` int(11) NOT NULL DEFAULT '0',
`createdate` int(11) NOT NULL,
`updatedate` int(11) NOT NULL,
`replys` int(11) NOT NULL,
`modifydate` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1540 DEFAULT CHARSET=utf8;
# Query_time: 114.958171 Lock_time: 0.000077 Rows_sent: 1 Rows_examined: 27389215
SET timestamp=1384932679;
SELECT * FROM `threads` where `createbyid` <> 22734 AND `id` in (SELECT `threadid` FROM `thread_replys` WHERE `userid` = 22734 GROUP BY `threadid`);
EXPALIN的结果
mysql> explain
-> SELECT * FROM `threads` where `createbyid` <> 24016 AND `id` in (SELECT `threadid` FROM `thread_replys` WHERE `userid` = 24016 GROUP BY `threadid`);
+----+--------------------+---------------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------------+-------+---------------+----------+---------+------+------+-------------+
| 1 | PRIMARY | threads | ALL | createbyid | NULL | NULL | NULL | 1505 | Using where |
| 2 | DEPENDENT SUBQUERY | thread_replys | index | NULL | threadid | 5 | NULL | 6 | Using where |
+----+--------------------+---------------+-------+---------------+----------+---------+------+------+-------------+
2 rows in set (0.00 sec)
threads表的问题: 1. content不应该嵌入在threads表里,单独成content表,thread里放content_id 2. createdby和replyedby用户名其实也不应该存在threads表里
threads和reply表记录数无疑会很多,这就要求这两个表的设计应该尽可能轻量。
如果不重新改表结构的话,你先试试把SELECT t.*改成SELECT t.id, 然后用另一组SQL再单独取出thread的具体内容。