MySQL慢联合查询

时间:2014-06-01 11:49:21

标签: mysql sql

我的查询如下:

SELECT address, min(nm_time) as first, max(nm_time) as last
        FROM (
            (SELECT tx_from as address, nm_time FROM tbl_transactions)
            UNION ALL
            (SELECT tx_to as address, nm_time FROM tbl_transactions)
        ) a
        GROUP by address
        ORDER BY first LIMIT 0,10

此查询大约需要5秒钟(在快速服务器上) 表tbl_transactions中有大约200,000条记录。我想要完成的是创建一个包含所有唯一地址及其第一个和最后一个事务时间戳的列表。我正在使用分页,因此LIMIT 0,10。 我有什么提示可以改善这个?

1 个答案:

答案 0 :(得分:2)

我不确定其中任何一个是否会有所帮助,但这里有两个想法。

要尝试的一件事是在子查询中进行聚合:

SELECT address, min(minnt) as first, max(maxnt) as last
FROM ((SELECT tx_from as address, min(nm_time) as minnt, max(nm_time) as maxnt
       FROM tbl_transactions
       GROUP BY tx_from
      )
      UNION ALL
      (SELECT tx_to as address, min(nm_time) as minnt, max(nm_time) as maxnt
       FROM tbl_transactions
       GROUP BY tx_to
      )
     ) a
GROUP by address
ORDER BY first
LIMIT 0, 10;

一种比聚合更快的方法是从地址列表开始,并使用相关的子查询来获取信息。为此,您需要一个地址表。查询看起来像:

SELECT a.address,
       least((select min(nm_time) from tbl_transactions t where t.tx_from = a.address),
             (select min(nm_time) from tbl_transactions t where t.tx_to = a.address)
            ) as first,
       least((select max(nm_time) from tbl_transactions t where t.tx_from = a.address),
             (select max(nm_time) from tbl_transactions t where t.tx_to = a.address)
            ) as last
FROM addresses a
ORDER BY first
LIMIT 10 OFFSET 0;

这需要两个性能指标:tbl_transactions(tx_from, nm_time)tbl_transactions(tx_to, nm_time)