Google bigquery 大查询分析函数提高了查询性能

Google bigquery 大查询分析函数提高了查询性能,google-bigquery,Google Bigquery,对于大型查询和在100M点数据集上遇到超时,这是一个非常新的问题。我试图找到我们在0(停止)附近达到一系列一致值的点,以及我们一直在0(开始)以上的点 我将确定开始文件时间的正在联接的子查询保存到它自己的数据集中,但这没有帮助。(通过多个“文件”以秒为增量 造成问题的部分是前一个临时秘书处和下一个临时秘书处的初步汇总 WITH test AS (SELECT 'A' as ACM, CAST('2017-01-01' AS DATE) as file_date, CAST('10:10:10'

对于大型查询和在100M点数据集上遇到超时,这是一个非常新的问题。我试图找到我们在0(停止)附近达到一系列一致值的点,以及我们一直在0(开始)以上的点

我将确定开始文件时间的正在联接的子查询保存到它自己的数据集中,但这没有帮助。(通过多个“文件”以秒为增量

造成问题的部分是前一个临时秘书处和下一个临时秘书处的初步汇总

WITH test AS
 (SELECT 'A' as ACM, CAST('2017-01-01' AS DATE) as file_date, CAST('10:10:10' AS TIME) as file_time , 0.0 as value, 0.1 as seconds
  UNION ALL SELECT 'A', '2017-01-01', '10:10:10', 0, 0.2 #start
  UNION ALL SELECT 'A', '2017-01-01', '10:10:10', 2000, 0.3
  UNION ALL SELECT 'A', '2017-01-01', '10:10:10', 1000, 0.4
  UNION ALL SELECT 'A', '2017-01-01', '10:10:10', 0, 0.5
  UNION ALL SELECT 'A', '2017-01-01', '10:10:10', -1000, 0.6
  UNION ALL SELECT 'A', '2017-01-01', '10:10:10', -2000, 0.7
  UNION ALL SELECT 'A', '2017-01-01', '10:10:10', 0, 0.8 #stop
  UNION ALL SELECT 'A', '2017-01-01', '10:10:10', 0, 0.9
  UNION ALL SELECT 'A', '2017-01-01', '10:10:11', 0, 1.0 #start
  UNION ALL SELECT 'A', '2017-01-01', '10:10:11', 1000, 1.1
  UNION ALL SELECT 'A', '2017-01-01', '10:10:11', 1000, 1.2
  UNION ALL SELECT 'A', '2017-01-01', '10:10:11', 2000, 1.3
  UNION ALL SELECT 'A', '2017-01-01', '10:10:11', 0, 1.4
  UNION ALL SELECT 'A', '2017-01-01', '10:10:11', 0, 1.5
  UNION ALL SELECT 'A', '2017-01-01', '10:10:11', -1000, 1.6
  UNION ALL SELECT 'A', '2017-01-01', '10:10:11', -2000, 1.7
  UNION ALL SELECT 'A', '2017-01-01', '10:10:11', 0, 1.8
  UNION ALL SELECT 'A', '2017-01-01', '10:10:11', 1000, 1.9
  UNION ALL SELECT 'A', '2017-01-01', '10:10:12', 2000, 2.0
  UNION ALL SELECT 'A', '2017-01-01', '10:10:12', 1000, 2.1 
  UNION ALL SELECT 'A', '2017-01-01', '10:10:12', 0, 2.2 #stop
  UNION ALL SELECT 'A', '2017-01-01', '10:10:12', 20, 2.3
  UNION ALL SELECT 'A', '2017-01-01', '10:10:12', 0, 2.4
  UNION ALL SELECT 'B', '2017-01-01', '10:10:10', 0, 0.1
  UNION ALL SELECT 'B', '2017-01-01', '10:10:10', 0, 0.2 #start
  UNION ALL SELECT 'B', '2017-01-01', '10:10:10', 2000, 0.3
  UNION ALL SELECT 'B', '2017-01-01', '10:10:10', 1000, 0.4
  UNION ALL SELECT 'B', '2017-01-01', '10:10:10', 0, 0.5
  UNION ALL SELECT 'B', '2017-01-01', '10:10:10', -1000, 0.6
  UNION ALL SELECT 'B', '2017-01-01', '10:10:10', -2000, 0.7
  UNION ALL SELECT 'B', '2017-01-01', '10:10:10', 0, 0.8 #stop
  UNION ALL SELECT 'B', '2017-01-01', '10:10:10', 0, 0.9
  UNION ALL SELECT 'B', '2017-01-01', '10:10:11', 0, 1.0 #start
  UNION ALL SELECT 'B', '2017-01-01', '10:10:11', 1000, 1.1
  UNION ALL SELECT 'B', '2017-01-01', '10:10:11', 1000, 1.2
  UNION ALL SELECT 'B', '2017-01-01', '10:10:11', 2000, 1.3
  UNION ALL SELECT 'B', '2017-01-01', '10:10:11', 0, 1.4
  UNION ALL SELECT 'B', '2017-01-01', '10:10:11', 0, 1.5
  UNION ALL SELECT 'B', '2017-01-01', '10:10:11', -1000, 1.6
  UNION ALL SELECT 'B', '2017-01-01', '10:10:11', -2000, 1.7
  UNION ALL SELECT 'B', '2017-01-01', '10:10:11', 0, 1.8
  UNION ALL SELECT 'B', '2017-01-01', '10:10:11', 1000, 1.9
  UNION ALL SELECT 'B', '2017-01-01', '10:10:12', 2000, 2.0
  UNION ALL SELECT 'B', '2017-01-01', '10:10:12', 1000, 2.1 
  UNION ALL SELECT 'B', '2017-01-01', '10:10:12', 0, 2.2 #stop
  UNION ALL SELECT 'B', '2017-01-01', '10:10:12', 20, 2.3
  UNION ALL SELECT 'B', '2017-01-01', '10:10:12', 0, 2.4 )
SELECT 
  acm,
  file_date,
  start_file_time,
  file_times,
  agg_sec as start_stop
FROM (
  SELECT 
    acm,
    file_date,
    start_file_time,
    file_times,
    ARRAY_AGG(kind) OVER w AS agg_kind, 
    ARRAY_AGG(seconds)  OVER w AS agg_sec
  FROM (
    SELECT
      acm,
      file_date,
      start_file_time,    
      ARRAY(SELECT DISTINCT x FROM UNNEST(file_times) as x) AS file_times,
      seconds, 
      CASE 
      WHEN (ABS(prev_val) < 50 and ABS(next_val) >= 50 and next_avg >= 50 and prev_avg < 50 ) THEN 'start'
      WHEN (ABS(next_val) < 50 and ABS(prev_val) >= 50 and prev_avg >= 50 and next_avg < 50 ) THEN 'stop'
      END as kind,
      prev_val, next_val, prev_avg, next_avg
    FROM (
      SELECT 
        s.acm as acm,
        s.file_date as file_date,
        s.start_file_time as start_file_time,
        seconds, 
        value,
        ARRAY_AGG(s.file_time) OVER (PARTITION BY s.acm, s.file_date, s.start_file_time) as file_times,
        AVG(ABS(value)) OVER prev as prev_avg,
        NTH_VALUE(value, 2) OVER prev as prev_val,
        AVG(ABS(value)) OVER next as next_avg,
        NTH_VALUE(value, 2) OVER next as next_val
      FROM test v
      JOIN (
        SELECT 
          acm,
          file_date,
          file_time,
          TIME_SUB(file_time, INTERVAL CAST(FLOOR(MIN(seconds)) AS INT64) SECOND) as start_file_time
        FROM test
        GROUP BY acm, file_date, file_time
      ) s ON s.acm = v.acm AND s.file_date = v.file_date AND s.file_time = v.file_time
      WINDOW prev AS (PARTITION BY s.acm, s.file_date, s.start_file_time ORDER BY seconds ROWS 2 PRECEDING), next AS (PARTITION BY s.acm, s.file_date, s.start_file_time ORDER BY seconds ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING)
      )
    WHERE value = 0)
  WHERE kind IN ('start', 'stop')
  WINDOW w AS (PARTITION BY acm, file_date, start_file_time ORDER BY seconds ROWS 1 PRECEDING))
WHERE ARRAY_LENGTH(agg_kind) = 2 AND agg_kind[ORDINAL(1)] = 'start' AND agg_kind[ORDINAL(2)] = 'stop'
;   
测试为
(选择A作为ACM,CAST('2017-01-01'作为日期)作为文件日期,CAST('10:10:10'作为时间)作为文件时间,0.0作为值,0.1作为秒
联合所有选择“A”、“2017-01-01”、“10:10:10”、0、0.2#开始
工会所有成员均选择“A”,“2017-01-01”,“10:10:10”,2000,0.3
联合所有选择“A”、“2017-01-01”、“10:10:10”、1000、0.4
联合所有选择“A”、“2017-01-01”、“10:10:10”、0、0.5
联合所有选择“A”、“2017-01-01”、“10:10:10”、“0.6”
联合所有选择“A”,“2017-01-01”,“10:10:10”,“2000,0.7”
联合所有选择“A”、“2017-01-01”、“10:10:10”、0、0.8#停止
联合所有选择“A”,“2017-01-01”,“10:10:10”,0,0.9
联合所有选择“A”、“2017-01-01”、“10:10:11”、0、1.0#开始
工会所有成员均选择“A”、“2017-01-01”、“10:10:11”、1000、1.1
工会所有成员均选择“A”、“2017-01-01”、“10:10:11”、1000、1.2
工会全体成员选择“A”,“2017-01-01”,“10:10:11”,2000,1.3
联合所有选择“A”、“2017-01-01”、“10:10:11”、0、1.4
联合所有选择“A”、“2017-01-01”、“10:10:11”、0、1.5
所有工会成员均选择“A”、“2017-01-01”、“10:10:11”、“1.6”和-1000
所有工会成员均选择“A”,“2017-01-01”,“10:10:11”,“2000年,1.7”
联合所有选择“A”、“2017-01-01”、“10:10:11”、0、1.8
所有工会成员均选择“A”、“2017-01-01”、“10:10:11”、1000、1.9
工会全体成员选择“A”,“2017-01-01”,“10:10:12”,2000,2.0
所有工会成员均选择“A”、“2017-01-01”、“10:10:12”、“1000”和“2.1”
联合所有人选择“A”、“2017-01-01”、“10:10:12”、“0、2.2”停止
工会所有成员均选择“A”、“2017-01-01”、“10:10:12”、“20”和“2.3”
联合所有选择“A”、“2017-01-01”、“10:10:12”、0、2.4
联合所有选择“B”,“2017-01-01”,“10:10:10”,0,0.1
联合所有选择“B”,“2017-01-01”,“10:10:10”,0,0.2#开始
工会全体成员选择“B”,“2017-01-01”,“10:10:10”,2000,0.3
联合所有选择“B”、“2017-01-01”、“10:10:10”、1000、0.4
联合所有选择“B”,“2017-01-01”,“10:10:10”,0,0.5
工会所有成员均选择“B”、“2017-01-01”、“10:10:10”、-1000、0.6
联合所有选择“B”,“2017-01-01”,“10:10:10”,“2000,0.7”
联合所有选择“B”、“2017-01-01”、“10:10:10”、0、0.8#停止
联合所有选择“B”,“2017-01-01”,“10:10:10”,0,0.9
联合所有选择“B”、“2017-01-01”、“10:10:11”、0、1.0#开始
工会所有成员选择“B”、“2017-01-01”、“10:10:11”、1000、1.1
所有工会成员都选择“B”、“2017-01-01”、“10:10:11”、1000、1.2
工会全体成员选择“B”,“2017-01-01”,“10:10:11”,2000,1.3
联合所有选择“B”、“2017-01-01”、“10:10:11”、0、1.4
联合所有选择“B”、“2017-01-01”、“10:10:11”、0、1.5
联合所有选择“B”、“2017-01-01”、“10:10:11”、“1.6”
所有工会成员都选择“B”,“2017-01-01”,“10:10:11”,“2000,1.7”
联合所有选择“B”、“2017-01-01”、“10:10:11”、0、1.8
工会所有成员都选择“B”,“2017-01-01”,“10:10:11”,1000,1.9
工会全体成员选择“B”,“2017-01-01”,“10:10:12”,2000,2.0
工会所有成员选择“B”、“2017-01-01”、“10:10:12”、1000、2.1
联合所有选择“B”、“2017-01-01”、“10:10:12”、0、2.2#停止
所有工会成员选择“B”、“2017-01-01”、“10:10:12”、“20”和“2.3”
联合所有选择“B”、“2017-01-01”、“10:10:12”、0、2.4)
挑选
acm,
存档日期,
开始文件时间,
档案室,
累计秒作为开始和停止
从(
挑选
acm,
存档日期,
开始文件时间,
档案室,
w上的数组集合(种类)作为集合集合种类,
阵列累积(秒)超过w作为累积秒
从(
挑选
acm,
存档日期,
开始文件时间,
数组(从UNNEST(file_times)中选择不同的x作为x)作为file_times,
秒,
案例
当(ABS(上一个值)<50,ABS(下一个值)>=50,下一个平均值>=50,上一个平均值<50)时,则“启动”
当(ABS(下一个值)<50且ABS(上一个值)>=50且上一个平均值>=50且下一个平均值<50)时,则“停止”
善终,
上一个值,下一个值,上一个平均值,下一个平均值
从(
挑选
s、 acm作为acm,
s、 文件日期作为文件日期,
s、 开始文件时间作为开始文件时间,
秒,
价值
将(按s.acm分区、s.file\u日期、s.start\u文件\u时间)上的数组\u AGG(s.file\u时间)作为文件\u时间,
平均值(ABS(值))高于上一个平均值作为上一个平均值,
上一个值的第n个值(值,2)作为上一个值,
下一个平均值(ABS(值))作为下一个平均值,
下一个上的第n个值(值,2)作为下一个值
从测试五开始
加入(
挑选
acm,
存档日期,
存档时间,
时间子(文件时间,间隔转换(地板(分钟(秒))为INT64)秒)为开始文件时间
从测试
按acm、文件日期、文件时间分组
)s ON s.acm=v.acm和s.file_日期=v.file_日期和s.file_时间=v.file_时间
窗口上一个AS(按s.acm划分,s.file_日期,s.start_文件_时间顺序,秒数,前2行),下一个AS(按s.acm划分,s.file_日期,s.start_文件_时间顺序,秒数,当前行和后2行之间)
)
其中值=0)
种类在哪里(“开始”、“停止”)
窗口w AS(按acm划分、文件\日期、开始\文件\时间顺序(按秒)(前1行))
其中,数组长度(agg_-kind)=2,agg_-kind[序数(1)]='start'和agg_-kind[序数(2)]='stop'
;   

检查以下版本是否会有所不同
我尽可能多地保留您的原始代码

#标准SQL
以测试为例
(选择A作为ACM,CAST('2017-01-01'作为日期)作为文件日期,CAST('10:10:10'作为时间)作为文件时间,0.0作为值,0.1作为秒
联合所有选择“A”、“2017-01-01”、“10:10:10”、0、0.2#开始
工会所有成员均选择“A”,“2017-01-01”,“10:10:10”,2000,0.3
联合所有选择“A”、“2017-01-01”、“10:10:10”、1000、0
SELECT
  * EXCEPT(file_data),
  ARRAY(SELECT STRUCT(seconds, kind) FROM UNNEST(file_data) WHERE kind IS NOT NULL) file_data
FROM(
  SELECT
    ACM,
    file_date,
    start_file_time,
    ARRAY(SELECT DISTINCT file_time FROM UNNEST(file_data)) file_times,
    ARRAY(SELECT STRUCT(seconds, IF(value = 0, (CASE WHEN ABS(NTH_VALUE(value, 2) OVER(prev)) < 50 AND ABS(NTH_VALUE(value, 2) OVER(next)) >= 50 AND AVG(ABS(value)) OVER(next) >= 50 and AVG(ABS(value)) OVER(prev) < 50 THEN 'start'
                                                    WHEN ABS(NTH_VALUE(value, 2) OVER(next)) < 50 AND ABS(NTH_VALUE(value, 2) OVER(prev)) >= 50 AND AVG(ABS(value)) OVER(prev) >= 50 and AVG(ABS(value)) OVER(next) < 50 THEN 'stop' END), NULL) as kind)
          FROM UNNEST(file_data)  WINDOW prev AS (ORDER BY seconds ROWS 2 PRECEDING), next as(ORDER BY seconds ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING)) file_data
  FROM(
    SELECT
      ACM,
      file_date,
      TIME_SUB(file_time, INTERVAL CAST(FLOOR(seconds) AS INT64) SECOND) AS start_file_time,
      ARRAY_AGG(STRUCT(file_time, value, seconds)) file_data
    FROM test
    GROUP BY ACM, file_date, start_file_time
   )
 )