Php Mysql子选择查询优化

Php Mysql子选择查询优化,php,sql,mysql,optimization,subquery,Php,Sql,Mysql,Optimization,Subquery,我每天都在运行一个查询来编译统计数据,但它看起来效率很低。以下是查询: SELECT a.id, tstamp, label_id, (SELECT author_id FROM b WHERE b.tid = a.id ORDER BY b.tstamp DESC LIMIT 1) AS author_id FROM a, b WHERE (status = '2' OR status = '3') AND category != 6 AND a.id = b.tid AND (b.type

我每天都在运行一个查询来编译统计数据,但它看起来效率很低。以下是查询:

SELECT a.id, tstamp, label_id, (SELECT author_id FROM b WHERE b.tid = a.id ORDER BY b.tstamp DESC LIMIT 1) AS author_id
FROM a, b
WHERE (status = '2' OR status = '3') 
AND category != 6
AND a.id = b.tid
AND (b.type = 'C' OR b.type = 'R')
AND a.tstamp1 BETWEEN {$timestamp_start} AND {$timestamp_end}
ORDER BY b.tstamp DESC
LIMIT 500
这个查询似乎运行得很慢。很抱歉命名错误-我被要求不要透露实际的表名

存在子选择的原因是,外部选择从表a获取一行,从表b获取一行。但是还需要知道表b中最新的作者id,所以我运行了一个子选择来返回该id。我不想在php循环中运行另一个select,因为这也是低效的

它工作正常-我只需要找到一种更快的获取此数据集的方法。

试试:

  SELECT a.id,
         b.tstamp,
         label_id,
         y.author_id
    FROM TABLE_A a
    JOIN TABLE_B b ON b.tid = a.id
    JOIN (SELECT b.tid,
                 MAX(b.tstamp) 'm_tstamp'
            FROM TABLE_B b
        GROUP BY b.tid) x ON x.tid = a.id
    JOIN (SELECT b.tid,
                 b.author_id,
                 b.tstamp
            FROM TABLE_B b
        GROUP BY b.tid) y ON y.tid = a.id
                         AND y.tstamp = x.m_tstamp
   WHERE status IN ('2', '3')
     AND b.type IN ('C', 'R')
     AND category != 6
     AND a.tstamp1 BETWEEN {$timestamp_start} AND {$timestamp_end}
ORDER BY b.tstamp DESC 
   LIMIT 500
尝试:


如果
b.tstamp
b.tid
中是唯一的,请使用OMG Ponies的解决方案

否则,您可以尝试此解决方案。它按照
b.tstamp DESC
对整个结果进行排序,并根据
作者id
添加排名。外部选择只取
rank=1
的行,这是每个
author\u id
具有最大
tstamp
的行

SELECT id, tstamp, label_id, author_id
  FROM (SELECT id,
               tstamp,
               label_id,
               author_id,
               CASE
                 WHEN @author_id != author_id THEN @row_num := 1 
                 ELSE @row_num := @row_num + 1
               END AS rank,
               @author_id := b.author_id
          FROM a,
               b,
               (SELECT @row_num := 0, @author_id := NULL) y
          WHERE a.id = b.tid
          AND (status = '2' OR status = '3') 
          AND category != 6
          AND (b.type = 'C' OR b.type = 'R')
          AND a.tstamp1 BETWEEN {$timestamp_start} AND {$timestamp_end}
          ORDER BY b.author_id, b.tstamp DESC
  ) x
 WHERE x.rank = 1
LIMIT 500

我没有尝试过,所以如果它不起作用,请评论。

如果
b.tstamp
b.tid
中是唯一的,请使用OMG Ponies的解决方案

否则,您可以尝试此解决方案。它按照
b.tstamp DESC
对整个结果进行排序,并根据
作者id
添加排名。外部选择只取
rank=1
的行,这是每个
author\u id
具有最大
tstamp
的行

SELECT id, tstamp, label_id, author_id
  FROM (SELECT id,
               tstamp,
               label_id,
               author_id,
               CASE
                 WHEN @author_id != author_id THEN @row_num := 1 
                 ELSE @row_num := @row_num + 1
               END AS rank,
               @author_id := b.author_id
          FROM a,
               b,
               (SELECT @row_num := 0, @author_id := NULL) y
          WHERE a.id = b.tid
          AND (status = '2' OR status = '3') 
          AND category != 6
          AND (b.type = 'C' OR b.type = 'R')
          AND a.tstamp1 BETWEEN {$timestamp_start} AND {$timestamp_end}
          ORDER BY b.author_id, b.tstamp DESC
  ) x
 WHERE x.rank = 1
LIMIT 500

我还没有试过,所以如果不起作用,请评论。

@Peter Lang:谢谢!更正。@Peter Lang:谢谢!更正。@马特:你应该尝试提供的答案,并接受解决问题的答案。如果他们都没有,考虑编辑你的问题提供更多的信息。”马特:你应该尝试提供的答案,赞成投票,接受一个解决你的问题。如果他们没有,考虑编辑你的问题提供更多的信息。