如果EXPLAIN仅显示400行,为什么MySQL SELECT查询需要1-2分钟才能运行?

瑞安

我需要从一个大表(7000万行)中获取最新的1000条记录,这些表通过两个简单表和小表上的INNER JOIN匹配几个索引良好的项目。

查询需要1-2分钟才能运行。然而,explain唯一显示的是要浏览的几百行。是什么赋予了?

如何优化查询或更有效地索引表,以使该查询在我期望的毫秒数内运行?

表格:

score    70,000,000 records
class           400 records
category        400 records

查询:

SELECT
    s.log_id,
    s.category_id
FROM
    score s
    INNER JOIN category ca ON s.category_id = ca.id
    INNER JOIN class cl ON ca.class_id = cl.id
WHERE
        s.score_status_type_id = 0
    AND ca.category_status_id = 1
    AND cl.class_status_id IN (1, 2)
    AND s.date > DATE_ADD(NOW(), INTERVAL -1440 minute)
GROUP BY s.log_id
ORDER BY s.date DESC
LIMIT 1000:

这是解释:

*** row 1 ***
          table:  cl
           type:  range
  possible_keys:  PRIMARY,class_status_id
            key:  class_status_id
        key_len:  4
            ref:  NULL
           rows:  36
          Extra:  Using where; Using index; Using temporary; Using filesort
*** row 2 ***
          table:  ca
           type:  ref
  possible_keys:  PRIMARY,class_id,category_status_id,category_status_id_class_id_id
            key:  category_status_id_class_id_id
        key_len:  8
            ref:  const,my_db.cl.id
           rows:  1
          Extra:  Using index
*** row 3 ***
          table:  s
           type:  ref
  possible_keys:  unique_key,category_id,date,score,score_status_type_id,score_status_and_date,category_id_score_status_type_id_date_log_id,date_reverse,category_id_date_reverse,score_date
            key:  category_id_score_status_type_id_date_log_id
        key_len:  8
            ref:  my_db.ca.id,const
           rows:  396
          Extra:  Using where; Using index

以下是一些创建表:

CREATE TABLE `score` (
  `log_id` bigint(20) NOT NULL,
  `profile_id` bigint(20) DEFAULT NULL,
  `date` datetime DEFAULT NULL,
  `class_id` int(11) NOT NULL,
  `score` float(10,6) DEFAULT NULL,
  `score_date` datetime DEFAULT NULL,
  `process_date` datetime DEFAULT NULL,
  `status_type_id` int(3) NOT NULL DEFAULT '0',
  `date_reverse` int(11) DEFAULT NULL,
  UNIQUE KEY `unique_key` (`log_id`,`class_id`),
  KEY `class_id` (`class_id`),
  KEY `profile_id` (`profile_id`),
  KEY `date` (`date`),
  KEY `score` (`score`),
  KEY `status_type_id` (`status_type_id `),
  KEY `status_type_id_date` (`status_type_id`,`date`),
  KEY `class_status_type_id_date_log_id` (`class_id`,`status_type_id`,`date`,`log_id`),
  KEY `date_reverse` (`date_reverse`),
  KEY `class_id_date_reverse` (`class_id`,`date_reverse`),
  KEY `date` (`date`),
  KEY `class_id_date_reverse_log_id` (`class_id`,`date_reverse`,`log_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `category` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `class_id` int(11) NOT NULL,
  `category_status_id` int(11) NOT NULL DEFAULT '0',
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `class_id` (`class_id`),
  KEY `name` (`name`),
  KEY `category_status_id_class_id_id` (`category_status_id`,`class_id`,`id`)
) ENGINE=InnoDB AUTO_INCREMENT=412 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

CREATE TABLE `class` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `class_status_id` int(11) NOT NULL DEFAULT '1',
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `person_id` (`person_id`),
  KEY `name` (`name`),
  KEY `class_status_id` (`class_status_id`),
  KEY `class_multi_1` (`class_status_id`,`name`,`id`)
) ENGINE=InnoDB AUTO_INCREMENT=407 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
波希米亚风格

问题在于该where子句是在进行联接应用过滤器,因此位于where子句中的联接表条件要求实际进行联接并将其放入临时结果集中(可能很大)。通常,优化程序会认识到条件可以在加入时声明,但是有时它可能有点密集,所以...

尝试将非关键条件移入联接

SELECT s.log_id, s.category_id
FROM score s
JOIN category ca ON s.category_id = ca.id
    AND ca.category_status_id = 1
JOIN class cl ON ca.class_id = cl.id
    AND cl.class_status_id IN (1, 2)
WHERE s.score_status_type_id = 0
AND s.date > DATE_ADD(NOW(), INTERVAL -1440 minute)
GROUP BY s.log_id
ORDER BY s.date DESC
LIMIT 1000

如果那还不能解决问题,请尝试首先score的子集作为子查询,然后进行联接。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么此MYSQL UPDATE查询需要2分钟才能运行?

来自分类Dev

mysql查询需要4分钟才能执行

来自分类Dev

简单的SQL查询需要20分钟才能运行?

来自分类Dev

我的旧显示器Samsung Syncmaster 740n需要2-3分钟才能打开

来自分类Dev

如果前后1分钟或2分钟,如何舍入到最接近的5分钟间隔?

来自分类Dev

如果使用Date(),为什么2个日期之间相差1分钟?

来自分类Dev

PowerShell的Stop-Job / StopJob()需要2分钟才能停止作业

来自分类Dev

仅运行setInterval 5分钟?

来自分类Dev

Ubuntu 需要一分钟才能启动

来自分类Dev

设置为让脚本在每1分钟触发内仅每2分钟发出一次呼叫的模式。(Google App脚本)

来自分类Dev

BigQuery今天还不算快-只有1行的表需要一分钟的查询时间

来自分类Dev

QODBC SELECT花费> 15分钟才能返回结果

来自分类Dev

Python Pandas缩短了目前需要约400分钟运行的大型数据集的计算时间

来自分类Dev

如果计算机正常运行时间大于5分钟,则需要帮助进行bash检查

来自分类Dev

如果Java进程在Websphere上运行了1分钟以上,则应用程序响应为500

来自分类Dev

如何使用石英在m子中每2分钟运行一次查询

来自分类Dev

PHP MySQL删除超过1分钟的行

来自分类Dev

Cron每1或2分钟就会运行一次

来自分类Dev

SQL查询需要35分钟

来自分类Dev

MySQL / Postgres查询5分钟间隔数据

来自分类Dev

使用熊猫仅保留timedelta = 1分钟的数据

来自分类Dev

GCMNetorkManager PeriodicTask只能使用1分钟,而不能使用2分钟

来自分类Dev

为什么我的Cron作业每隔1小时设置一次,却每隔1分钟运行一次?

来自分类Dev

为什么我的Cron作业每隔1小时设置一次,却每隔1分钟运行一次?

来自分类Dev

如果提前1,2,3,4分钟,如何将其四舍五入到最接近的5分钟间隔?

来自分类Dev

为什么我的cron配置的GitHub Action无法每2分钟运行一次?

来自分类Dev

Kubuntu需要超过2分钟的启动时间!

来自分类Dev

为什么Linux发行版可以立即协调USB设备,但是Windows需要1分钟以上的时间?

来自分类Dev

在SQL Server中,使用.modify()XQuery删除节点需要38分钟才能执行

Related 相关文章

  1. 1

    为什么此MYSQL UPDATE查询需要2分钟才能运行?

  2. 2

    mysql查询需要4分钟才能执行

  3. 3

    简单的SQL查询需要20分钟才能运行?

  4. 4

    我的旧显示器Samsung Syncmaster 740n需要2-3分钟才能打开

  5. 5

    如果前后1分钟或2分钟,如何舍入到最接近的5分钟间隔?

  6. 6

    如果使用Date(),为什么2个日期之间相差1分钟?

  7. 7

    PowerShell的Stop-Job / StopJob()需要2分钟才能停止作业

  8. 8

    仅运行setInterval 5分钟?

  9. 9

    Ubuntu 需要一分钟才能启动

  10. 10

    设置为让脚本在每1分钟触发内仅每2分钟发出一次呼叫的模式。(Google App脚本)

  11. 11

    BigQuery今天还不算快-只有1行的表需要一分钟的查询时间

  12. 12

    QODBC SELECT花费> 15分钟才能返回结果

  13. 13

    Python Pandas缩短了目前需要约400分钟运行的大型数据集的计算时间

  14. 14

    如果计算机正常运行时间大于5分钟,则需要帮助进行bash检查

  15. 15

    如果Java进程在Websphere上运行了1分钟以上,则应用程序响应为500

  16. 16

    如何使用石英在m子中每2分钟运行一次查询

  17. 17

    PHP MySQL删除超过1分钟的行

  18. 18

    Cron每1或2分钟就会运行一次

  19. 19

    SQL查询需要35分钟

  20. 20

    MySQL / Postgres查询5分钟间隔数据

  21. 21

    使用熊猫仅保留timedelta = 1分钟的数据

  22. 22

    GCMNetorkManager PeriodicTask只能使用1分钟,而不能使用2分钟

  23. 23

    为什么我的Cron作业每隔1小时设置一次,却每隔1分钟运行一次?

  24. 24

    为什么我的Cron作业每隔1小时设置一次,却每隔1分钟运行一次?

  25. 25

    如果提前1,2,3,4分钟,如何将其四舍五入到最接近的5分钟间隔?

  26. 26

    为什么我的cron配置的GitHub Action无法每2分钟运行一次?

  27. 27

    Kubuntu需要超过2分钟的启动时间!

  28. 28

    为什么Linux发行版可以立即协调USB设备,但是Windows需要1分钟以上的时间?

  29. 29

    在SQL Server中,使用.modify()XQuery删除节点需要38分钟才能执行

热门标签

归档