如何通过查询加快组中最近记录的返回速度

时间:2018-03-14 13:19:25

标签: mysql

我正在尝试从GROUP BY mysql查询返回最新记录。

我的数据如下:

id  | user_id | rate_gbp    | active | created_at
===============================================================
1   | 5       | 10.000000   | 1      | 2016-05-19 18:42:55
2   | 6       | 10.000000   | 0      | 2016-05-19 18:42:58
3   | 7       | 10.000000   | 0      | 2016-05-19 18:42:59
4   | 8       | 10.000000   | 0      | 2016-05-19 18:43:01
5   | 9       | 10.000000   | 1      | 2016-05-19 18:43:03
6   | 10      | 10.000000   | 0      | 2016-05-19 18:43:05
7   | 11      | 10.000000   | 0      | 2016-05-19 18:43:07
8   | 12      | 10.000000   | 0      | 2016-05-19 18:43:09

有些记录在一天内被多次修改,我想每天只提取最新记录。

我尝试过像这样的解决方案:SQL Show most recent record in GROUP BY?看起来像这样:

SELECT
  *
FROM (SELECT
  user_id,
  date_format(rates.created_at, '%Y-%m-%d') AS sday,
  MAX(rates.created_at) AS latest_record
FROM rates
GROUP BY id,
         sday) r1
LEFT JOIN (SELECT
  *
FROM rates) r2
  ON r2.created_at = rates.latest_record
  AND r2.user_id = rates.user_id
GROUP BY r1.user_id,
         r2.sday

这样可行,但比我想要的慢。

我还使用了SUBSTRING_INDEX(GROUP_CONCAT...但是这会发出警告,表示正在删除行,不幸的是我无权更改group_concat_max_len的值(目前为1024)。

有更有效的方法吗?

2 个答案:

答案 0 :(得分:0)

首先添加此索引:

ALTER TABLE `rates` ADD INDEX `rates_idx_id_id_at` (`id`, `user_id`, `created_at`);

此外,将FROM子句中的子查询提取到临时表,索引它们然后加入应该比加入子查询要快得多,子查询在很多情况下是不可索引的。

以下内容可以帮助您创建临时表,索引它们,然后运行连接它们的查询:

-- Transformed subquery to a temp table to improve performance
CREATE TEMPORARY TABLE IF NOT EXISTS temp1 AS SELECT
        rates.user_id,
        date_format(rates.created_at,
        '%Y-%m-%d') AS sday,
        MAX(rates.created_at) AS latest_record 
    FROM
        rates 
    GROUP BY
        rates.id,
        sday 
    ORDER BY
        NULL;

-- Transformed subquery to a temp table to improve performance
CREATE TEMPORARY TABLE IF NOT EXISTS temp2 AS SELECT
        * 
    FROM
        rates;

-- This index is required for optimal temp tables performance
ALTER TABLE
  `temp1`
ADD
  INDEX `temp1_idx_id` (`user_id`);

-- This index is required for optimal temp tables performance
ALTER TABLE
  `temp2`
ADD
  INDEX `temp2_idx_at_id_sday` (`created_at`, `user_id`, `sday`);

SELECT
        * 
    FROM
        temp1 r1 
    LEFT JOIN
        temp2 r2 
            ON r2.created_at = rates.latest_record 
            AND r2.user_id = rates.user_id 
    GROUP BY
        r1.user_id,
        r2.sday 
    ORDER BY
        NULL

答案 1 :(得分:-1)

  select * from table group by created_at,rate_gbp order by created_at desc