我有大量的历史数据,我想按月分组。我正在准备下面的HP Vertica数据库查询,以按月分组我的数据。
SELECT
Region, Country,
TO_TIMESTAMP(TO_CHAR(Order_Date,'m/yyyy'),'m/yyyy') as MONTH_Order_Date,
SUM(CAST(Unit_Price as NUMERIC(37,15))) as Sum_Unit_Price,
SUM(CAST(Total_Revenue as NUMERIC(37,15))) as Sum_Total_Revenue
FROM SalesRecords
GROUP BY Region,Country,TO_TIMESTAMP(TO_CHAR(Order_Date,'m/yyyy'),'m/yyyy')
ORDER BY Region ASC,Country ASC,TO_TIMESTAMP(TO_CHAR(Order_Date,'m/yyyy'),'m/yyyy') ASC
现在这个查询的问题是性能,超过10亿个数据需要花费近2分钟,并且分组后的返回记录设置为10万行。 我需要以下面显示的格式显示数据,因为我需要在数据库级别解析日期以获取格式化日期,这种格式在数据库服务器上花费时间。
请建议我可以使用的任何其他方式因为在同一个表上如果我在其他列上分组数据,除了日期类型列表现良好,返回记录设置几乎在40秒内超过10亿条记录。
我需要为所有主要的RDBMS执行此性能。
Region Country MONTH_Order_Date Sum_Unit_Price Sum_Total_Revenue
Asia Bangladesh 2010-01-01 00:00:00 186252.349999999999937 920607119.140000001169023
Asia Bangladesh 2011-01-01 00:00:00 186456.190000000000641 931633189.440000000452752
Asia Bangladesh 2012-01-01 00:00:00 194925.550000000000312 969718040.969999998663069
Asia Bangladesh 2013-01-01 00:00:00 194048.289999999999566 1017253078.219999998891571
Asia Bangladesh 2014-01-01 00:00:00 184143.090000000000413 915867255.449999996567606
Asia Bangladesh 2015-01-01 00:00:00 193697.769999999999864 959097995.869999999053554
Asia Bangladesh 2016-01-01 00:00:00 184833.730000000000529 955360230.500000001682568
Asia Bangladesh 2017-01-01 00:00:00 111476.840000000000014 563824376.189999998257226
Asia Bhutan 2010-01-01 00:00:00 186506.900000000000474 916963415.479999997623498
答案 0 :(得分:1)
Vertica游程编码(RLE)允许您利用低基数列来提高查询性能和磁盘空间节省,并且将非常精细的数据类型(如时间戳)转换为mmyyyy可能非常适合这项工作。
1)将mmyyyy转换放入数据加载过程
2)使用名为month_year的新计算列创建一个新投影,并格式化为mmyyyy。
3)在投影列列表和投影ORDER BY中,将此卡和其他低卡列放在列表的开头。高卡列位于列表的末尾。但是任何高卡连接列(如密钥)应该紧跟在低卡列之后。
4)请务必在此卡和所有其他低卡列上指定ENCODING_RLE。
这两个指向Vertica文档的链接解释了所涉及的概念:
答案 1 :(得分:0)
按年份或月份分组,您可以使用:
GROUP BY YEAR(Order_Date)
或MONTH(Order_Date)
但是你的数据太大了,我们无法尝试在最后测试它,只有你可以进行实际的数学运算。
答案 2 :(得分:0)
我试试这个 - 每次改变都会加快一点,而这一切的总和可能会带来好的最终结果:
SELECT
Region
, Country
, YEAR(order_date)*100+month(order_date) AS yearmonth
-- extracting integers from dates is faster than TO_CHAR()
-- and the result is INTEGER - the fastest type to GROUP BY ...
, CAST(SUM(Unit_Price ) AS NUMERIC(37, 15)) AS Sum_Unit_Price
, CAST(SUM(Total_Revenue) AS NUMERIC(37, 15)) AS Sum_Total_Revenue
-- instead of CAST-ing each input value, CAST the final grouping
-- result once
FROM SalesRecords
GROUP BY 1,2,3 -- sometimes the optimizer is clever enough -
ORDER BY 1,2,3 -- but this ensures no repeated expression evaluation
;
祝你好运
马