改进BigQuery不区分大小写的搜索性能

时间:2018-01-24 07:13:31

标签: performance google-bigquery

  

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 个答案:

答案 0 :(得分:10)

  

团队注意事项:敬请期待!很快BigQuery就会变成这样   建议无关紧要。

BigQuery性能提示:避免使用LOWER()UPPER()

处理Unicode文本时,

LOWER()UPPER()操作很难处理:每个字符都需要单独映射,也可以是多字节。

解决方案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个搜索字词:34s至9s
  • 3个搜索词:52s到11s。

解决方案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

7s中的3个词 - 很好。

解决方案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)修饰符。

如果这对您有用,请随时评论您的效果改进