我正在使用MySQL 5.6。我创建了一个包含 366 个分区的表来按天保存数据,这意味着一年中我们最多有 366 天,所以我在该表上创建了 366 个分区。哈希分区由一个整数列管理,该列为每条记录存储 1 到 366。
Report_Summary表:
CREATE TABLE `Report_Summary` (
`PartitionsID` int(4) unsigned NOT NULL,
`ReportTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`Amount` int(10) NOT NULL,
UNIQUE KEY `UNIQUE` (`PartitionsID`,`ReportTime`),
KEY `PartitionsID` (`PartitionsID`),
KEY `ReportTime` (`ReportTime`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED
/*!50100 PARTITION BY HASH (PartitionsID)
PARTITIONS 366 */
我目前的查询:
SELECT DATE(RS.ReportTime) AS ReportDate, SUM(RS.Amount) AS Total
FROM Report_Summary RS
WHERE RS.ReportTime >= '2014-12-26 00:00:00' AND RS.ReportTime <= '2014-12-30 23:59:59' AND
RS.PartitionsID BETWEEN DAYOFYEAR('2014-12-26 00:00:00') AND DAYOFYEAR('2014-12-30 23:59:59')
GROUP BY ReportDate;
上面的查询运行良好,并且使用分区p360到p364来获取数据。现在的问题是当我将fromDate 传递给 '2014-12-26' 并将 toDate 传递给 '2015-01-01'然后上面的查询将不起作用。因为“2015-01-01”的年份是1,所以我的条件失败了。
现在我尝试在IN运算符中传递值,然后它在查询下面的数据库检查中完美运行:
SELECT DATE(RS.ReportTime) AS ReportDate, SUM(RS.Amount) AS Total
FROM Report_Summary RS
WHERE RS.ReportTime >= '2014-12-26 00:00:00' AND RS.ReportTime <= '2015-01-01 23:59:59' AND
RS.PartitionsID IN (360,361,362,363,364,365,1)
GROUP BY ReportDate;
为了生成上述场景,我创建了一个函数并传递了两个日期并生成了一个逗号分隔的 ID 字符串
SELECT GenerateRange('2014-12-26 00:00:00', '2015-01-01 23:59:59');
这将我的数据返回为:
'360,361,362,363,364,365,366,1'
我尝试在我的查询中使用该函数,所以我将查询更改如下:
SELECT DATE(RS.ReportTime) AS ReportDate, SUM(RS.Amount) AS Total
FROM Report_Summary RS
WHERE RS.ReportTime >= '2014-12-26 00:00:00' AND RS.ReportTime <= '2015-01-01 23:59:59' AND
FIND_IN_SET(RS.PartitionsID, GenerateRange('2014-12-26 00:00:00', '2015-01-01 00:00:00'))
GROUP BY ReportDate;
然后我使用EXPLAIN PARTITION SELECT...检查了上述查询的执行计划。我发现我的条件行不通。它使用所有分区来获取数据。我只想使用这些日期的特定分区。必须只检查这360,361,362,363,364,365,366,1分区意味着p360到p366和p1。
为什么我的查询不起作用?这不是实现这个的正确方法然后我想要解决方案我该如何实现呢?
我从编码中知道我可以实现它,但我必须编写一个查询来实现它。
谢谢...