我有以下查询,它花费了这么多时间&>表大小为64.31 GB,是否有可能对此进行重写?

SELECT MIN(ut.id) AS minUT, 
       MAX(ut.id) AS maxUT
FROM user_tasks ut
    JOIN user_tasks_metadata utm ON utm.user_task_id = ut.id
    JOIN ue_events_base ue ON ue.usr_task_id = ut.id
    JOIN batch_records br ON ut.id = br.user_task_id
WHERE ut.id > (
                SELECT IFNULL(MAX(assp.user_task_id_end) , 0) 
                FROM app_summary_snapshot_points assp
              )
AND br.created_at < (current_timestamp() - INTERVAL 10 MINUTE) 
AND br.is_subscription_updated = 1 
HAVING minUT > 0 and maxUT > 0;

行扫描次数

*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: ue
   partitions: NULL
         type: range
possible_keys: ue_events_user_task_id_events
          key: ue_events_user_task_id_events
      key_len: 8
          ref: NULL
         rows: 1722
     filtered: 100.00
        Extra: Using where; Using index
*************************** 2. row ***************************
           id: 1
  select_type: PRIMARY
        table: br
   partitions: NULL
         type: ref
possible_keys: batch_created_at,batch_user_task
          key: batch_user_task
      key_len: 9
          ref: ue_stage.ue.usr_task_id
         rows: 1
     filtered: 5.00
        Extra: Using where
*************************** 3. row ***************************
           id: 1
  select_type: PRIMARY
        table: ut
   partitions: NULL
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 8
          ref: ue_stage.ue.usr_task_id
         rows: 1
     filtered: 100.00
        Extra: Using index
*************************** 4. row ***************************
           id: 1
  select_type: PRIMARY
        table: utm
   partitions: NULL
         type: ref
possible_keys: usertask_fk_idx,id_asi
          key: id_asi
      key_len: 8
          ref: ue_stage.ue.usr_task_id
         rows: 1
     filtered: 100.00
        Extra: Using index

Br表没有某些组合索引,但该查询是否可以重写?

推荐答案

您的batch_records表的WHERE过滤器查找

AND br.created_at < (current_timestamp() - INTERVAL 10 MINUTE) 
AND br.is_subscription_updated = 1 

因此,像这样的复合(多列)覆盖索引将有助于提高性能.

ALTER TABLE batch_records ADD INDEX upd_cre_uti
        (is_subscription, created_at DESC, user_task_id);

MySQL可以随机访问该索引到第一个符合条件的行...正确值为is_subscription且最大值为created_at的那个.然后,它可以按顺序扫描索引到最后符合条件的行.当它正在扫描时,它可以从索引中取出user_task_id.

我不认为有一种有用的查询重构可以解决您的性能问题:索引是解决这类问题的规范方法.

Mysql相关问答推荐

根据时间戳分组删除

按唯一列排序,但保持匹配的列在一起

是否可以使用以EXPLAIN EXTENDED ...开头的 SQL 语句修改数据?

排序子查询结果并返回每个 ID 的第一行

Select 并统计所有条目并根据条目对它们进行分组

MYSQL 删除两个已知字符串之间的字符串

此更新查询是否有任何可能的重写选项?

如何获取从开始时间到结束时间的所有正在运行的作业(job)的总和?

查询获取日期之间的可数匹配条目并加入它们以读取用户状态

MySQL表中给定字段的每个不同值的连续记录形成对

如何使用 SQL 聚合和求和相似 Select 的值?

用数字和字母对 VARCHAR 列进行排序

Mysql 相等性反对 false 或 true

MYSQL 或 Laravel Eloquent 如何从这个订单中统计细节

我将如何构建一个 SQL 查询来从交易表中 Select 第一次存款、第二次存款和额外存款

如何使用 C++ 连接 mySQL 数据库

没有 JDBC 类型的方言映射:1111

错误 1396 (HY000): 'user'@'localhost' 的操作 DROP USER 失败

如何从命令行调用带有参数的mysql存储过程?

MySQL讲解查询理解