繁体   English   中英

MySQL多个日期子查询

[英]MySQL multiple Date subqueries

我正在为一个非常具体的报告编写查询,该报告包含基于项目的特定关系的可变列数。 我愿意就如何更改查询提出建议,但我认为不可能。 我宁愿将其保留为单个查询,而不是循环运行。 正在搜索的表包含大约400万条记录,无法存档。

我想知道的是,为什么在子查询中不使用DATEADD索引,尽管在同一表的外部查询中使用了DATEADD索引。 我知道字段上的函数使MySQL无法建立索引,但这仅在项目上,而不是您要与之进行比较的项目。

报告的结果是该范围内发生日期的每个日期的每个特定项目(子查询)的数字。 日期范围是动态生成的。 子查询应返回一天的结果

我们正在使用MySQL 5.0.77版本,由于它是由托管服务提供商管理的,因此无法更改。

这是查询:

 SELECT DATE_FORMAT(DATEADD, '%d/%m/%y') AS DATEADD,

   (SELECT COUNT(ID)
      FROM ATABLE AS 
     WHERE ELEMNAME = 'ANELEMENT' AND COMPID = 132
           AND VT.DATEADD BETWEEN CONCAT(DATE(V.DATEADD)," 00:00:00") AND CONCAT(DATE(V.DATEADD)," 23:59:59")))
      AS '132',

   (SELECT COUNT(ID)
      FROM ATABLE AS 
     WHERE ELEMNAME = 'ANELEMENT' AND COMPID = 149
           AND VT.DATEADD BETWEEN CONCAT(DATE(V.DATEADD)," 00:00:00") AND CONCAT(DATE(V.DATEADD)," 23:59:59")))
      AS '149'

 FROM ATABLE AS V
WHERE 1 = 1 AND COMPID = 132
   AND (V.DATEADD >= "2010-09-01 00:00:00"
        AND V.DATEADD <= "2010-10-26 23:59:59")
   AND 1 = 1
   AND ELEMNAME = 'ANELEMENT'
GROUP BY DATE_FORMAT(DATEADD, '%Y-%m-%d')

子查询的运行次数取决于该项目所具有的链接数,并在构建查询时确定。

我们已经尝试过:用

"VT.DATEADD <= DATE(V.DATEADD) and VT.DATEADD <= DATE(V.DATEADD) +1" 

但是,这也不起作用,将其更改为

"VT.DATEADD = DATE(V.DATEADD)" 

确实使用了索引,但是没有返回正确的行数,因为DATEADD是日期时间。 如果我们将其更改为:

"VT.DATEADD >= "2010-09-01" AND VT.DATEADD <= "2010-09-02"

Explain的输出是

+----+--------------------+-------+-------+-------------------------+----------+---------+-------+-------+----------------------------------------------+
| id | select_type        | table | type  | possible_keys           | key      | key_len | ref   | rows  | Extra                                        |
+----+--------------------+-------+-------+-------------------------+----------+---------+-------+-------+----------------------------------------------+
|  1 | PRIMARY            | V     | range | DATEADD,COMPID,ELEMNAME | DATEADD  | 8       | NULL  |  1386 | Using where; Using temporary; Using filesort |
|  2 | DEPENDENT SUBQUERY | VT    | ref   | COMPID,ELEMNAME         | ELEMNAME | 103     | const | 44277 | Using where                                  |
+----+--------------------+-------+-------+-------------------------+----------+---------+-------+-------+----------------------------------------------+

使用USE INDEX或FORCE INDEX(在可用但未使用时)使用NULL键

在不解决此问题的情况下,即使在很小的日期范围内,查询的运行速度也非常慢,并且将数据库锁定。

我不知道我是否过度简化了总体需求,但是这一点对您有用。 您似乎想知道在给定日期范围内两个“ compli”值的活动量。

SELECT 
      DATE_FORMAT(DATEADD, '%Y-%m-%d'),
      SUM( if( compid = 132, 1, 0 ) ) as Count132,
      SUM( if( compid = 149, 1, 0 ) ) as Count149
   from
      ATable 
   where
          elemname = "ANELEMENT"
      AND ( compid = 132 or compid = 149 )
      AND DATEADD BETWEEN "2010-09-01 00:00:00" AND "2010-10-26 23:59:59"
   group by
      dateadd

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM