【问题标题】:MySQL doesn't use indexes in a SELECT clause subqueryMySQL 不在 SELECT 子句子查询中使用索引
【发布时间】:2016-09-30 09:19:00
【问题描述】:

我有一个“事件”表

table events
  id (pk, auto inc, unsigned int)
  field1,
  field2,
  ...
  date DATETIME (indexed)

我正在尝试分析交通中的漏洞(一天中有 0 个事件的时刻)

我试试这种请求

SELECT
    e1.date AS date1,
    (
        SELECT date
        FROM events AS e2
        WHERE e2.date > e1.date
        LIMIT 1
    ) AS date2
FROM events AS e1
WHERE e1.date > NOW() -INTERVAL 10 DAY

需要很长时间

这里是解释

+----+--------------------+-------+-------+---------------------+---------------------+---------+------+----------+-------------+
| id | select_type        | table | type  | possible_keys       | key                 | key_len | ref  | rows     | Extra       |
+----+--------------------+-------+-------+---------------------+---------------------+---------+------+----------+-------------+
|  1 | PRIMARY            | t1    | range | DATE                | DATE                | 6       | NULL |        1 | Using where |
|  2 | DEPENDENT SUBQUERY | t2    | ALL   | DATE                | NULL                | NULL    | NULL | 58678524 | Using where |
+----+--------------------+-------+-------+---------------------+---------------------+---------+------+----------+-------------+
2 rows in set (0.00 sec)

在 MySQL 5.5 上测试

为什么 mysql 不能使用 DATE 索引?是因为子查询吗?

【问题讨论】:

  • events 表中有多少行?
  • 约6000万
  • 可能是错字WHERE e1 > NOW() -INTERVAL 10 DAY。应该是这样的:WHERE e1.date > NOW() -INTERVAL 10 DAY
  • 我修复了查询(谢谢)
  • 您能告诉我们您要做什么吗?可能正在重组查询可能使用索引。

标签: mysql optimization indexing subquery


【解决方案1】:

您正在寻找没有事件的日期?

首先建立一个表Days,其中包含所有可能的日期(dy)。这将使您度过平静的日子:

SELECT dy
    FROM Days
    WHERE NOT EXISTS ( SELECT * FROM events
                        WHERE date >= days.day
                          AND date  < days.day + INTERVAL 1 DAY )
      AND dy > NOW() -INTERVAL 10 DAY

请注意,5.6 在这方面做了一些优化。

【讨论】:

  • 这是我要应用的替代方案……但令人失望的是 MySQL 5.5 不处理这种子查询。如果我有更多时间,我会尝试再次测试 5.6 或 5.7 Thx 以获得帮助
【解决方案2】:

您的查询遇到了here 所示的问题,该问题还提供了一个使用临时表的快速解决方案。那是一个 mysql 论坛页面,所有这些都是我通过找到 this Stackoverflow 问题挖掘出来的。

您可能会发现动态创建和填充这样的新表会产生可承受的性能,并且在日期时间范围 now() 少于 10 天的情况下很容易实现。

如果您在制作任何东西时需要帮助,请告诉我。我看看能不能帮忙。

【讨论】:

  • 谢谢,但我知道 MySQL 还没有准备好使用 SUBQUERIES...我必须找到另一种方法来分析流量中的漏洞
  • 如果我能提供帮助,请告诉我。不确定流量漏洞是什么意思,除非您的意思是与您的活动和下一个活动问题(差距)有关
  • 孔是间隙。我想检测没有流量的时段实现此目的的另一种方法是 GROUP BY SUBSTR(date, 1, 16)。我将有所有的交通时间。我会通过这个查询找到与外部脚本的差距。
  • 我很乐意提供帮助。但我需要以表格形式显示的样本数据和预期结果
猜你喜欢
  • 2015-06-19
  • 1970-01-01
  • 2019-09-15
  • 2021-11-16
  • 2014-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多