SQL 百分位数计算运行非常缓慢 - 需要帮助加快速度
Posted
技术标签:
【中文标题】SQL 百分位数计算运行非常缓慢 - 需要帮助加快速度【英文标题】:SQL percentile calculation running very slowly - need help speeding it up 【发布时间】:2017-09-17 19:21:33 【问题描述】:我有一个大表(目前大约有 8.5 亿行),并且需要每周计算百分位值,因为插入了新数据并且静态数据变脏了。但是,该过程非常慢(我的硬件/当前查询需要 5-6 小时)。
如何更改我的查询以加快查询速度?
现在,我的查询基本上是这样的:
SELECT DISTINCT [ident1]
,[ident2]
,[ident3]
,[ident4]
,percentile_cont(0.05)
WITHIN GROUP (
ORDER BY [value] ASC
) OVER (
PARTITION BY [ident1]
,[ident2]
,[ident3]
,[ident4]
) AS [percentile_5]
,percentile_cont(0.10)
WITHIN GROUP (
ORDER BY [value] ASC
) OVER (
PARTITION BY [ident1]
,[ident2]
,[ident3]
,[ident4]
) AS [percentile_10]
,percentile_cont(0.25)
WITHIN GROUP (
ORDER BY [value] ASC
) OVER (
PARTITION BY [ident1]
,[ident2]
,[ident3]
,[ident4]
) AS [percentile_25]
,percentile_cont(0.50)
WITHIN GROUP (
ORDER BY [value] ASC
) OVER (
PARTITION BY [ident1]
,[ident2]
,[ident3]
,[ident4]
) AS [percentile_50]
,percentile_cont(0.75)
WITHIN GROUP (
ORDER BY [value] ASC
) OVER (
PARTITION BY [ident1]
,[ident2]
,[ident3]
,[ident4]
) AS [percentile_75]
,percentile_cont(0.90)
WITHIN GROUP (
ORDER BY [value] ASC
) OVER (
PARTITION BY [ident1]
,[ident2]
,[ident3]
,[ident4]
) AS [percentile_90]
,percentile_cont(0.95)
WITHIN GROUP (
ORDER BY [value] ASC
) OVER (
PARTITION BY [ident1]
,[ident2]
,[ident3]
,[ident4]
) AS [percentile_95]
FROM dataTable
我认为问题的一部分是,如果没有DISTINCT
选择,我在数据库中的每个值都会得到一行。 SQL 是否足够聪明,可以只为每个组计算一次百分位数?还是对每个值重复计算?
任何帮助将不胜感激。
【问题讨论】:
你需要 percentile_cont 还是可以使用 percentile_disc? 执行计划告诉您有关此查询的什么信息? (首先要看的地方应该是执行计划。)例如,它可能会识别缺失的索引。 我正在制定执行计划。我的 DBA 目前禁用了该功能。与此同时,索引这个的最佳方法是什么? [ident1]、[ident2]、[ident3]、[ident4] 和 [value] 上的聚集索引?或者可能是列的某个子集? 【参考方案1】:将 distinct 放入子查询中:
select . . .
from (select distinct . . . ) s;
distinct
应该在 计算完所有 select
列之后发生。
【讨论】:
这不会改变执行计划,Windowed Aggregates 是在 beforedistinct
计算的
@dnoeth 。 . .确切地。如果给定行有 100 个副本,它们将被计算 100 次。据推测,OP 在应用 distinct 后想要窗口函数值。
但是百分位数通常是在完整的数据集上计算的,事先应用 DISTINCT 可能会改变结果。
@dnoeth 。 . .我发现我使用select distinct
的实例很少,而没有窗口函数的实例。我只能模糊地猜测 OP 可能真正想要什么。
SQL Server 只实现了Window版本,但是OP想要Aggregate版本percentile_cont(0.05) WITHIN GROUP ( ORDER BY [value] ASC ) ... GROUP BY [ident1] ,[ident2] ,[ident3] ,[ident4]
以上是关于SQL 百分位数计算运行非常缓慢 - 需要帮助加快速度的主要内容,如果未能解决你的问题,请参考以下文章