提高 BigQuery 不区分大小写的搜索性能
Posted
技术标签:
【中文标题】提高 BigQuery 不区分大小写的搜索性能【英文标题】:Improve BigQuery case insensitive search performance 【发布时间】:2018-01-24 07:13:30 【问题描述】:BigQuery 团队再次出击:这个问题不再相关,因为现在使用 LOWER() 的结果与使用 REGEX() 的结果一样快。
使用 BigQuery 处理大约 5GB 的数据应该非常快。例如,以下查询在 18 秒内执行不区分大小写的搜索:
#standardSQL
SELECT COUNT(*) c
FROM `bigquery-public-data.hacker_news.full`
WHERE
LOWER(text) LIKE '%bigquery%' # 18s
通常 BigQuery 比这更快,但真正的问题是添加新的搜索词会使这个查询变得相当慢(几乎一分钟,有 3 个搜索词):
#standardSQL
SELECT COUNT(*) c
FROM `bigquery-public-data.hacker_news.full`
WHERE
LOWER(text) LIKE '%bigquery%' OR LOWER(text) LIKE '%big query%' # 34s
#standardSQL
SELECT COUNT(*) c
FROM `bigquery-public-data.hacker_news.full`
WHERE
LOWER(text) LIKE '%bigquery%' OR LOWER(text) LIKE '%big query%'
OR LOWER(text) LIKE '%google cloud%' # 52s
如何提高查询性能?
【问题讨论】:
【参考方案1】:团队注意事项:敬请期待!很快 BigQuery 将把它变成 建议无关紧要。
BigQuery 性能提示:避免使用 LOWER()
和 UPPER()
LOWER()
和 UPPER()
操作在处理 Unicode 文本时会遇到困难:每个字符都需要单独映射,它们也可以是多字节。
解决方案 1:不区分大小写的正则表达式
更快的选择:使用REGEX_MATCH()
并将不区分大小写的(?i)
修饰符添加到您的正则表达式中
#standardSQL
SELECT COUNT(*) c
FROM `bigquery-public-data.hacker_news.full`
WHERE
REGEXP_CONTAINS(text, '(?i)bigquery') # 7s
# REGEXP_CONTAINS(text, '(?i)bigquery')
# OR REGEXP_CONTAINS(text, '(?i)big query') # 9s
# REGEXP_CONTAINS(text, '(?i)bigquery')
# OR REGEXP_CONTAINS(text, '(?i)big query')
# OR REGEXP_CONTAINS(text, '(?i)google cloud') # 11s
这样性能会好很多:
1 个搜索词:18s 到 8s 2 个搜索词:34 秒到 9 秒 3 个搜索词:52 秒到 11 秒。解决方案 2:组合正则表达式
当一个正则表达式可以将多个组合为 1 时,为什么要进行 3 次搜索?
#standardSQL
SELECT COUNT(*) c
FROM `bigquery-public-data.hacker_news.full`
WHERE
REGEXP_CONTAINS(text, '(?i)(bigquery|big query|google cloud)') # 7s
3 个词在 7 秒内 - 不错。
解决方案 3:转换为字节
这更难看,但表明 UPPER()
和 LOWER()
在处理单个字节时表现得更好 - 在这些搜索中获得相同的结果:
#standardSQL
SELECT COUNT(*) c
FROM `bigquery-public-data.hacker_news.full`
WHERE
LOWER(CAST(text AS BYTES)) LIKE b'%bigquery%'
OR LOWER(CAST(text AS BYTES)) LIKE b'%big query%'
OR LOWER(CAST(text AS BYTES)) LIKE b'%google cloud%' # 7s
LOWER() 比较慢。请改用正则表达式 (?i) 修饰符。
如果这对您有用,请随时评论您的性能改进。
【讨论】:
感谢 Elliot Brossard 的提示! 更短的解决方案 2(类似性能):REGEXP_CONTAINS(text, '(?i)(big( )?query|google cloud)') 是的 - 但只是因为我为这个例子选择了类似的字符串:)以上是关于提高 BigQuery 不区分大小写的搜索性能的主要内容,如果未能解决你的问题,请参考以下文章