这是表结构
CREATE TABLE IF NOT EXISTS `msg` (
  `id` int(10) NOT NULL auto_increment,
  `userid` int(10) NOT NULL default '0' COMMENT '发送者ID',
  `sender` varchar(32) NOT NULL default '',
  `touserid` int(10) NOT NULL default '0' COMMENT '接收者ID',
  `receiver` varchar(32) NOT NULL default '',
  `content` varchar(255) NOT NULL default '',
  `threadid` int(10) NOT NULL default '0' COMMENT '本次话题ID',
  `created` int(10) NOT NULL default '0',
  `flag` tinyint(1) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `userid` (`userid`),
  KEY `touserid` (`touserid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;INSERT INTO `msg` (`id`, `userid`, `sender`, `touserid`, `receiver`, `content`, `threadid`, `created`, `flag`) VALUES
(1, 1, '雷风', 2, '援用制', '消息111', 1, 0, 0),
(2, 2, '援用制', 1, '雷风', '援用制的第一次回复', 1, 0, 0),
(3, 2, '援用制', 1, '雷风', '援用制的第二次回复', 1, 0, 0),
(4, 1, '雷风', 2, '援用制', '雷风的第一次回复', 1, 0, 0),
(5, 1, '雷风', 2, '援用制', '消息222', 5, 0, 0),
(6, 3, '黎明', 1, '雷风', '黎明的第一次回复', 6, 0, 0);我想查询出所有touserid=1的记录,这些记录按照话题ID(既threadid)分组,每组只取最新的一条回复(回复应该按时间到序排列,这里暂且以主键到序排列),并且要查处该话题的话题总数。例如threadid=1的记录数有4条,那查处的cnt就等于4下面是我的sql,这个查询能不能优化下,我explain它发现它太恐怖了,特别当数据量大的时候
select tmp.*,tmp2.cnt from (select sender,receiver,content,threadid from msg where touserid = 1 order by id desc) tmp 
inner join (select threadid,count(*) as cnt from msg where (userid = 1 or touserid = 1) group by threadid) tmp2 
on tmp.threadid = tmp2.threadid group by tmp.threadid
+--------+----------+--------------------+----------+-----+
| sender | receiver | content            | threadid | cnt |
+--------+----------+--------------------+----------+-----+
| 援用制 | 雷风     | 援用制的第二次回复 |        1 |   4 |
| 黎明   | 雷风     | 黎明的第一次回复   |        6 |   1 |
+--------+----------+--------------------+----------+-----+

解决方案 »

  1.   

    select threadid,count(*) as cnt from msg where (userid = 1 or touserid = 1->select threadid,count(*) as cnt from 
    (select * from msg where userid = 1 
    union all
    select * from msg where touserid = 1) a
    group by threadid
      

  2.   

    大哥好象不行啊,这是我的sql 可能查询数是 3*3*6*2
    id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra  
    1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using temporary; Using filesort 
    1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where 
    3 DERIVED msg ALL userid,touserid NULL NULL NULL 6 Using where; Using temporary; Using filesort 
    2 DERIVED msg ALL touserid touserid 4   2 Using filesort 你的sql 查询数是 3*3*6*2*2*2
    id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra  
    1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using temporary; Using filesort 
    1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where 
    3 DERIVED <derived4> ALL NULL NULL NULL NULL 6 Using temporary; Using filesort 
    4 DERIVED msg ref userid userid 4   2   
    5 UNION msg ref touserid touserid 4   2   
    NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL   
    2 DERIVED msg ALL touserid touserid 4   2 Using filesort 其实我就想把我接受到的短信息按照threadid分组,取每个分组的最新条记录,并且统计话题数
      

  3.   

    不会吧,测试一下
    select threadid,count(*) as cnt from msg where (userid = 1 or touserid = 1)select * from msg where userid = 1 
    union all 
    select * from msg where touserid = 1记录数是否一样
     
      

  4.   

    那别管我的sql了,按照以下结果,这个sql该怎么写呢
    +--------+----------+--------------------+----------+-----+ 
    | sender | receiver | content            | threadid | cnt | 
    +--------+----------+--------------------+----------+-----+ 
    | 援用制 | 雷风    | 援用制的第二次回复 |        1 |  4 | 
    | 黎明  | 雷风    | 黎明的第一次回复  |        6 |  1 | 
    +--------+----------+--------------------+----------+-----+ 
      

  5.   

    try:
    select a.userid,a.sender,a.threadid,a.created,a.flag,count(b.id),max(c.content)
    from (select * from msg where touserid=1) a
    left join
    (select * from msg where touserid=1) b
    on a.sender=b.sender and a.receiver=b.receiver
    left join msg c
    on a.userid=c.userid and a.threadid=c.threadid
    group by a.userid,a.sender,a.threadid,a.created,a.flag
      

  6.   

    可以将select * from msg where touserid=1
    生成视图
      

  7.   

    修改:
    select a.userid,a.sender,a.threadid,a.created,a.flag,count(b.id) as cnt,
    max(a.id) as id,max(c.content) 
    from (select * from msg where touserid=1) a
    left join
    (select * from msg where touserid=1) b
    on a.sender=b.sender and a.receiver=b.receiver
    left join msg c
    on a.id=c.id  
    group by a.userid,a.sender,a.threadid,a.created,a.flag也可以
    select a1.*,c.content from (
    select a.userid,a.sender,a.threadid,a.created,a.flag,count(b.id) as cnt,
    max(a.id) as id 
    from (select * from msg where touserid=1) a
    left join
    (select * from msg where touserid=1) b
    on a.sender=b.sender and a.receiver=b.receiver
    group by a.userid,a.sender,a.threadid,a.created,a.flag) a1
    left join msg c
    on a1.id=c.id