[英]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.