MySQL查询以获取表中多个不同项目的最新记录

时间:2019-04-26 05:23:21

标签: mysql

我无法将数据从表中拉出,因为它花费的时间太长,而且会降低系统速度。

这是参考表:

CREATE TABLE IF NOT EXISTS `User_Table` (
    `user_table_id`  int unsigned        not null auto_increment,
    `user_id`        int unsigned        not null,
    `unixtimes`      int unsigned        not null,
    `status`         char(1)             not null default '',
    `text1`          text                not null,
    `text2`          text                not null,
PRIMARY KEY (`user_table_id`),
UNIQUE INDEX user_table_1 (`user_id`, `status`, `unixtimes`),
UNIQUE INDEX User_Table_2 (user_id, unixtimes, status)
);

status可以是四个值之一;

  • 'a'=已批准
  • 'd'=拒绝
  • 'p'=待处理
  • 's'=已跳过

我试图多次连接同一张表。最终目标是单个记录,其中包含user_id(以便可以与其他用户表连接到user表),最新的待处理文本和最新的已批准文本(如果存在),以便可以进行比较。

| user_id | login | pending_text1 | pending_text2 | current_text1 | current_text1 |
|---------|-------|---------------|---------------|---------------|---------------|
| 8675309 | Bob   | Second entry  | Second other  | First entry   | First other   |

如果有所作为,则对于任何给定的user_id,都应仅记录一条标记为待处理的记录。审核未决记录,并更新记录以批准或拒绝。如果在查看现有的暂挂记录之前有新的暂挂记录进入,则旧记录将更新为跳过,仅留下一个未决记录。

还应注意,我主要关注查看最新的未决记录,并且可能没有任何批准的记录。例如,在第一次审核期间,只能有一个待处理。这就是为什么我一直在使用LEFT JOIN。

这是我一直在使用的查询的精简版本,但每次至少花费4-5秒,但记录少于10万。由于记录的数量只能增加,因此我希望查询能获得更好的回报。

SELECT
    `up`.`user_id` AS 'user_id',
    `u`.`login` AS 'login',
    `up`.`text1` AS 'pending_text1',
    `up`.`text2` AS 'pending_text2',
    `record_current`.`text1` AS 'current_text1',
    `record_current`.`text2` AS 'current_text2'

FROM
    `user_table` up
JOIN
    `user` u
ON    `up`.`user_id` = `u`.`user_id`

LEFT JOIN (
    SELECT
        `up`.*
    FROM
        `user_table` up
    JOIN (
        SELECT
            `user_id`, MAX(`unixtimes`) unixtimes 
        FROM 
            `user_table` 
        WHERE
            `status` = 'a'
        GROUP BY
            `user_id`) all_approved
    ON 
        `up`.`user_id` = `all_approved`.`user_id` AND `up`.`unixtimes` = `all_approved`.`unixtimes`) record_current
ON 
    `up`.`user_id` = `record_current`.`user_id`

WHERE 
    `up`.`status` = 'p'
ORDER BY 
    `up`.`unixtimes`;

有什么想法吗?

更新: 添加了第二个索引:UNIQUE INDEX User_Table_2 (user_id, unixtimes, status) 在问题中添加EXPLAIN:

| id  | select_type | table        | type   | possible_keys                 | key          | key_len | ref                                         | rows  | filtered | Extra                                        |
|-----|-------------|--------------|--------|-------------------------------|--------------|---------|---------------------------------------------|-------|----------|----------------------------------------------|
| 1   | PRIMARY     | up           | ALL    | User_Table_1,User_Table_2     | null         | null    | null                                        | 93858 | 75.0     | Using where; Using temporary; Using filesort |
| 1   | PRIMARY     | u            | eq_ref | PRIMARY                       | PRIMARY      | 4       | dbase.up.user_id                            | 1     | 100.0    |                                              |
| 1   | PRIMARY     | <derived2>   | ALL    | null                          | null         | null    | null                                        | 82793 | 100.0    |                                              |
| 2   | DERIVED     | <derived3>   | ALL    | null                          | null         | null    | null                                        | 82793 | 100.0    |                                              |
| 2   | DERIVED     | up           | ref    | User_Table_1,User_Table_2     | User_Table_2 | 8       | all_approved.user_id,all_approved.unixtimes | 469   | 100.0    |                                              |
| 3   | DERIVED     | User_Table   | range  | null                          | User_Table_1 | 5       | null                                        | 10    | 100.0    | Using where; Using index for group-by        |

0 个答案:

没有答案