选择命中顺序的查询消耗大量数据
Query for selecting sequence of hits consumes large quantity of data
我正在尝试通过网站上的替代渠道衡量转化率。我的查询旨在输出查看相关开始 URL 的会话计数和严格按该顺序点击确认页面的会话计数。它通过比较命中时间来做到这一点。
我的查询似乎 return 准确的数字,但这样做会选择大量数据,对于我试图限制在一天中的一小时内的数据,不到 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
这个查询为什么要处理如此多的数据?有没有更好的方法来获取这些数字。理想情况下,任何方法都应该能够测量多条不同的路线,但此时我会满足于可持续性。
可能有几种方法可以优化您的查询,但它似乎无法完全解决您的问题(我将进一步尝试解释)。
至于查询,这个查询也是一样,但是避免了 re-selecting 数据和 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
(我在其中使用术语 "catalog" 和 "product"),last_hn
跟踪确认 URLs(我使用术语 "success" 但可以在 regex
选择器中添加更多值)。此外,通过使用 MIN
和 MAX
操作以及 analytical functions,您可以在查询中进行一些优化。
这里有几点要说明:
- 如果您插入
WHERE hits.hithour = 20
,BigQuery 仍然必须扫描整个 table 以找出哪些不是 20。这意味着你观察到的23Gbs仍然占了一整天。
- 为了比较,我根据我们的 ga_sessions 测试了您的查询,大约需要 31 天才能达到 23Gb 的数据.由于您没有选择那么多字段,因此达到这个数量应该不会那么容易,除非您的数据源有相当高的流量。
- 鉴于 BigQuery 目前的 pricing,23Gbs 将消耗你大约 0.11 美元来处理,这相当 cost-efficient。
- 我可以想象的另一件事是,您每天多次 运行 此查询,并且没有
cache
或这些操作的适当架构。
综上所述,您可以优化您的查询,但我怀疑它最终不会改变那么多,因为看起来您的数据量相当大。处理 23Gbs 几次应该不是问题,但如果您担心它会达到您的配额,那么您似乎每天要 运行 多次此查询。
在这种情况下,看看使用一些 cache
标志或将结果保存到另一个 table 然后查询它是否会有所帮助。此外,您可以开始每天 table 只保存您感兴趣的会话(具有您正在寻找的 URL 模式),然后 运行 您在这些新创建的 tables,这将允许您查询更大范围的天数,花费更少。
我正在尝试通过网站上的替代渠道衡量转化率。我的查询旨在输出查看相关开始 URL 的会话计数和严格按该顺序点击确认页面的会话计数。它通过比较命中时间来做到这一点。
我的查询似乎 return 准确的数字,但这样做会选择大量数据,对于我试图限制在一天中的一小时内的数据,不到 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
这个查询为什么要处理如此多的数据?有没有更好的方法来获取这些数字。理想情况下,任何方法都应该能够测量多条不同的路线,但此时我会满足于可持续性。
可能有几种方法可以优化您的查询,但它似乎无法完全解决您的问题(我将进一步尝试解释)。
至于查询,这个查询也是一样,但是避免了 re-selecting 数据和 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
(我在其中使用术语 "catalog" 和 "product"),last_hn
跟踪确认 URLs(我使用术语 "success" 但可以在 regex
选择器中添加更多值)。此外,通过使用 MIN
和 MAX
操作以及 analytical functions,您可以在查询中进行一些优化。
这里有几点要说明:
- 如果您插入
WHERE hits.hithour = 20
,BigQuery 仍然必须扫描整个 table 以找出哪些不是 20。这意味着你观察到的23Gbs仍然占了一整天。 - 为了比较,我根据我们的 ga_sessions 测试了您的查询,大约需要 31 天才能达到 23Gb 的数据.由于您没有选择那么多字段,因此达到这个数量应该不会那么容易,除非您的数据源有相当高的流量。
- 鉴于 BigQuery 目前的 pricing,23Gbs 将消耗你大约 0.11 美元来处理,这相当 cost-efficient。
- 我可以想象的另一件事是,您每天多次 运行 此查询,并且没有
cache
或这些操作的适当架构。
综上所述,您可以优化您的查询,但我怀疑它最终不会改变那么多,因为看起来您的数据量相当大。处理 23Gbs 几次应该不是问题,但如果您担心它会达到您的配额,那么您似乎每天要 运行 多次此查询。
在这种情况下,看看使用一些 cache
标志或将结果保存到另一个 table 然后查询它是否会有所帮助。此外,您可以开始每天 table 只保存您感兴趣的会话(具有您正在寻找的 URL 模式),然后 运行 您在这些新创建的 tables,这将允许您查询更大范围的天数,花费更少。