查询命中序列的查询消耗大量数据

时间:2017-01-13 15:22:56

标签: sql google-analytics google-bigquery standard-sql

我试图通过网站上的其他渠道衡量转化率。我的查询旨在输出查看相关起始URL的会话计数以及严格按此顺序点击确认页面的会话计数。它通过比较命中次数来做到这一点。

我的查询似乎返回了准确的数字,但这样做会选择大量的数据,只有不到23GB,我试图将其限制为一天中的一小时。我似乎没有以特别有效的方式编写我的查询,并认为如果我继续使用它,我会很快用完我公司的所有数据配额。

以下是完整的违规查询:

WITH 
s1 AS (
  SELECT
      fullVisitorId,
      visitId,    
      LOWER(h.page.pagePath),
      device.deviceCategory AS platform,
      MIN(h.time) AS s1_time
  FROM
    `project.dataset.ga_sessions_*`, UNNEST(hits) AS h 
  WHERE
    _TABLE_SUFFIX BETWEEN '20170107' AND '20170107'
  AND
    LOWER(h.page.pagePath) LIKE '{funnel-start-url-1}%' OR LOWER(h.page.pagePath) LIKE '{funnel-start-url-2}%'
  AND
    totals.visits = 1
  AND
    h.hour  < 21
  AND
    h.hour >= 20      
  AND
    h.type = "PAGE"
  GROUP BY
    path,
    platform,
    fullVisitorId,
    visitId
  ORDER BY
    fullVisitorId ASC, visitId ASC
),

confirmations AS (
  SELECT
      fullVisitorId,
      visitId,
      MIN(h.time) AS confirmation_time
  FROM
    `project.dataset.ga_sessions_*`, UNNEST(hits) AS h 
  WHERE
    _TABLE_SUFFIX BETWEEN '20170107' AND '20170107'
  AND
    h.type = "PAGE"      
  AND
    LOWER(h.page.pagePath) LIKE '{confirmation-url-1}%' OR LOWER(h.page.pagePath) LIKE '{confirmations-url-2}%'
  AND
    totals.visits = 1
  AND
    h.hour  < 21
  AND
    h.hour >= 20
  GROUP BY
    fullVisitorId,
    visitId
)

SELECT
  platform,
  path,
  COUNT(path) AS Views,
  SUM(
    CASE 
      WHEN s1.s1_time < confirmations.confirmation_time 
      THEN 1 
      ELSE 0 
    END
  ) AS SubsequentPurchases
FROM
  s1
LEFT JOIN
  confirmations
ON
  s1.fullVisitorId = confirmations.fullVisitorId
AND
  s1.visitId = confirmations.visitId
GROUP BY
  platform,
  path

这个查询有什么意义,它必须处理这么多数据?有没有更好的方法来获得这些数字。理想情况下,任何方法都应该能够衡量多种不同的路线,但我现在已经满足于可持续性。

1 个答案:

答案 0 :(得分:1)

可能有一些方法可以优化您的查询,但似乎它不能完全解决您的问题(因为我将进一步尝试解释)。

对于查询,这个查询相同,但避免重新选择数据和LEFT JOIN操作:

SELECT
    path,
    platform,
    COUNT(path) views,
    COUNT(CASE WHEN last_hn > first_hn THEN 1 END) SubsequentPurchases
from(
SELECT
    fv,
    v,
    platform,
    path,
    first_hn,
    MAX(last_hn) OVER(PARTITION BY fv, v) last_hn
from(
SELECT 
    fullvisitorid fv,
    visitid v,
    device.devicecategory platform,
    LOWER(hits.page.pagepath) path,
    MIN(CASE WHEN REGEXP_CONTAINS(hits.page.pagepath, r'/catalog/|product') THEN hits.hitnumber ELSE null END) first_hn,
    MAX(CASE WHEN REGEXP_CONTAINS(hits.page.pagepath, r'success') then hits.hitnumber ELSE null END) last_hn
FROM `project_id.data_set.ga_sessions_20170112`,
UNNEST(hits) hits
WHERE 
    REGEXP_CONTAINS(hits.page.pagepath, r'/catalog/|product|success')
    AND totals.visits = 1
    AND hits.type = 'PAGE'
GROUP BY 
    fv, v, path, platform
)
)
GROUP BY
    path, platform
HAVING NOT REGEXP_CONTAINS(path, r'success')

first_hn跟踪funnel-start-url(其中我使用了条款&#34;目录&#34;&#34;产品&#34;)和last_hn跟踪确认网址(我使用了术语&#34;成功&#34;但可以在regex选择器中添加更多值)。此外,通过使用MINMAX操作以及analytical functions,您可以在查询中进行一些优化。

这里有几点要点:

  1. 如果您插入WHERE hits.hithour = 20,BigQuery仍然需要扫描整个表格以查找不是20的内容。这意味着你观察到的23Gbs仍​​然占据了一整天。
  2. 为了进行比较,我针对 ga_sessions 测试了您的查询,并且花了 31 天来达到23Gb的数据。由于您没有选择那么多字段,因此除非您的数据源有相当高的流量,否则不应该很容易达到此数量。
  3. 鉴于BigQuery的当前pricing,23Gbs将耗费大约0.11美元来处理,这非常具有成本效益。
  4. 我能想象的另一件事是你每天都要运行这个查询几次,而且这些操作没有cache或一些适当的架构。
  5. 所有这一切,你可以优化你的查询,但我怀疑它最终不会改变那么多,因为你似乎有相当大的数据量。处理23Gbs几次不应该是一个问题,但如果你担心它会达到你的配额,那么看起来你每天都要运行几次这个查询。

    在这种情况下,看看是使用某个cache标志还是将结果保存到另一个表中,然后查询它将有所帮助。此外,您可以仅使用您感兴趣的会话(具有您正在查找的URL模式)开始保存每日表,然后在这些新创建的表中运行最终查询,这样您就可以在更大的天数内查询花费少得多。