是否可以像在嵌套字段上一样快地过滤嵌套字段?

时间:2019-07-15 02:15:35

标签: google-bigquery

我不确定使用嵌套结构时如何优化表架构。

想象一下,我在BigQuery中有一个具有以下架构的表:

USER
firstName: string
lastName: string
accountID: string
posts: [
    {
     title: string
     body: string
     postID: string
    }
]

如果我要选择标题为“ Hello World!”的用户,查询会比选择firstName =“ Jose”的用户慢得多吗?换句话说,如果查询嵌套值,是否会失去柱状存储的速度优势?

为每种查询类型创建一个单独的表会更好吗?换句话说,当我想按用户的顶级属性进行过滤时,有一个带有嵌套帖子的User表,而当我想按Post属性进行过滤时,也有带有嵌套用户的Post表吗?

3 个答案:

答案 0 :(得分:1)

  

如果我要选择标题为“ Hello World!”的用户,查询会比选择firstName =“ Jose”的用户慢得多吗?

不,它不会慢很多。两者都将同样缓慢。但是请注意:慢速是一个相对的概念-一个人会认为快速-其他人会认为慢速,反之亦然。如果您需要几秒钟的时间-BigQuery不是您的选择!但是,如果您需要几秒钟的时间-一定会得到的,并且一定会喜欢BigQuery的功能

  

换句话说,如果查询嵌套值,是否会失去柱状存储的速度优势?

您实际上在这里利用了列式存储的速度,甚至对于嵌套值

  

为每种查询类型创建一个单独的表会更好吗?

不,这不会更好-理想情况下(对于BigQuery),应保持数据尽可能非规范化。显然,仍然需要某种程度的规范化,但代价是JOIN的性能和冗余存储数据的成本

答案 1 :(得分:0)

推荐:

select
  *
from
  USER
where
  exists(select 1 from unnest(posts) where title = 'Hello World!')

比较: 嵌套结构中的筛选比创建另一个POST表更快。这种策略也称为denormalized table,您可以在下面查看链接

Denormalization

答案 2 :(得分:0)

不管数据库的类型如何,当通过嵌套字段(即使在像BigQuery这样的列式db系统中)进行过滤时,您实际上是在发出UNNEST语句来对嵌套列进行任何过滤。这意味着您将至少执行n x m操作(其中n是行数,m是嵌套列中的字段数)。< / p>

例如,要运行所需的查询,您将必须执行以下操作:

select * from `mydataset.USERS`, unnest(posts) as x
where x.title = "Hello World!"

这就是说,是的,在关系数据库系统中管理数据的理想方法是相应地进行结构化。您可以随时将posts保存在单独的表中,该表可以具有以下结构:

select accountID, x.postID, x.title, x.body
from `mydataset.USERS`, UNNEST(posts) as x

然后使用JOIN获取所需数据:

select U.accountID, P.postID, P.title, P.body
from `mydataset.USERS` U 
join `mydataset.posts` P on U.accountID = P.accountID
where P.title = "Hello World!"

希望有帮助。