作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
在我的职业生涯中, 我不得不为不同类型的报告和图表编写复杂的分析查询. 大多数情况下,它是一些图表,显示按日期、星期、季度等汇总的数据. 通常, 创建这样的报告是为了帮助客户识别趋势,并说明他们的业务是如何在高水平上执行的. 但是当 数据科学家和工程师 需要基于大数据集创建一个更广泛的报告?
如果报告是基于小数据集, 该任务可以通过在关系数据库下编写SQL查询来解决. 在这一步中, 了解编写查询的基础知识以及如何使查询更快、更高效是很重要的. 然而,有时报告依赖于一个更大的数据集(例如.g. 数百万甚至更多的表行), 但是报告不依赖于输入变量(参数)。, 或者您可能会发现值的数量非常少. 在这种情况下, SQL查询可能很慢, 因此,对于用户来说,等待查询被执行并不是最佳选择. 在这种情况下,最常见的做法是在客户端请求报告之前提前运行查询.
也, 它需要实现一些缓存功能, 因此,客户端可以从缓存中获取数据,而不是实时运行查询. 如果不需要显示实时数据,这种方法可以完美地工作. 它可以显示一小时甚至一天前计算的数据. 因此,实际的报告/图表是使用缓存数据显示的,而不是基于实时数据.
当时我在制药行业做一个分析项目, 我需要以邮政编码和药物名称作为输入参数的图表. 我还需要展示美国特定地区药物之间的一些比较.
分析查询非常复杂,最终在我们的Postgres服务器(四核CPU和16gb RAM)上运行了大约50分钟。. 我无法提前运行它并缓存结果, 因为查询以邮政编码和药物作为输入参数, 所以有成千上万种组合, 而且不可能预测哪个客户会选择.
即使我想尝试执行所有的输入参数组合, 我的数据库很可能会崩溃. 所以是时候选择一种不同的方法,选择一些易于使用的解决方案. 那张图表对客户很重要, 然而, 客户端还没有准备好对架构进行重大更改或完全迁移到另一个数据库.
在这个项目中,我们尝试了几种不同的方法:
最后,我们尝试了 谷歌BigQuery. 它满足了我们的期望,使我们能够在不做客户不愿批准的巨大改变的情况下完成工作. 但是谷歌BigQuery是什么,它是如何执行的?
BigQuery是一个基于rest的web服务,它允许您在大型数据集下运行复杂的基于sql的分析查询. 在我们将数据上传到BigQuery并执行与之前相同的查询之后 Postgres (语法出奇地相似), 我们的查询运行得快得多,大约需要一分钟才能完成. 最终,我们通过使用不同的服务获得了50倍的性能提升. 值得注意的是,其他db没有提供相同的性能增益, 让我们宽宏大量地说,他们甚至没有接近. 说实话, 我对BigQuery提供的性能提升印象深刻, 因为这些数据比我们所有人预期的都要好.
尽管如此,我不会宣称BigQuery是世界上最好的数据库解决方案. 虽然它对我们的项目很有效, 它仍然有很多局限性, 例如,每天对表的更新次数有限, 每个请求的数据大小限制, 和其他人. 您需要了解BigQuery不能用于替代关系数据库, 它是面向运行分析查询的, 而不是简单的CRUD操作和查询.
在本文中, 我将尝试比较使用Postgres(我最喜欢的关系数据库)和BigQuery的实际用例场景. 也, 在此过程中,我将提供一些建议, 也就是我对何时使用BigQuery是有意义的看法.
比较Postgres和谷歌BigQuery, 我把每个国家的公共人口统计信息按国家分组, 年龄, 年份和性别(你可以从这里下载相同的数据 link).
我将数据添加到四个表中:
人口
位置
年龄_groups
人口_aggregated
最后一个表只是聚合了来自前三个表的数据. 下面是DB模式:
的 人口
最后得到的表包含6个以上.900万行. 虽然不多,但对我的考试来说已经足够了.
基于样本数据, 我尝试构建可用于构建现实生活中的分析报告和图表的查询. 因此,我为下一个报告准备了查询:
查询# 1, #2, 第6条非常简单直接, 但是第三个问题, #4, 第5条不太好写——至少对我来说是这样. 请注意,我是一名后端工程师,编写复杂的SQL查询并不是我的专长, 因此,有更多SQL经验的人可能会构建更智能的查询. 然而, 现在我们需要检查一下Postgres和BigQuery是如何用相同的数据处理相同的查询的.
我总共构建了24个查询:
人口
, 位置
, 年龄_groups
)人口_aggregated
table让我来分享一下聚合数据的BigQuery查询#1和#5,这样你就可以理解简单查询(#1)和复杂查询(# 5)的复杂性.
美国人口按年合计查询:
select
总和(值),
一年
从
world_population.人口_aggregated
在哪里
location_name = 'United States of America'
集团
2
命令
年asc
查询每年每个国家的年龄中位数,按最年长到最年轻排序:
——将年龄转换为数字
将population_by_年龄_一年_and_location设置为(
select
Sum (value)作为value,
Cast (regexp_replace(年龄_group_name, '\\+', ") as int64) as 年龄,
一年,
location_name
从
world_population.人口_aggregated
在哪里
location_type = '国家'
按2,3,4分组),
——计算每个国家每年的总人口
Total_population_by_一年_and_位置 as (
select
Sum (value)作为value,
一年,
location_name
从
population_by_年龄_一年_and_location
集团
2,3
),
-计算每年在该国的总人数
Age_multiplied_by_population_temp
select
Sum (value * 年龄)作为value,
一年,
location_name
从
population_by_年龄_一年_and_location
集团
2,3
),
Median_per_一年_country = (
select
a.值/ b.值为中值,
a.一年,
a.location_name
从
年龄_multiplied_by_population_temp一
内部连接total_population_by_一年_and_位置 b on a.Location_name = b.Location_name和a.年= b.一年
)
从median_per_一年_country中选择*
按年份排序,按中位数排序
注意:您可以在我的bitbucket存储库中找到所有查询(链接在文章末尾).
为了运行查询,我使用了两个不同的Postgres服务器. 第一个有1个CPU核心和4GB RAM,由SSD驱动器支持. 第二个有16个CPU内核, 64GB RAM,也使用SSD驱动器(第二台服务器有16倍的CPU和RAM潜力).
另外,请注意,在运行测试期间,数据库上没有负载. 我创建它们只是为了运行查询. 在现实生活中, 查询将花费更长的时间, 因为其他查询可能同时运行, 另外, 那些并行运行的查询可能会锁定表. 为了检查查询速度,我使用了pgAdmin3和BigQuery web界面.
在我的测试中,我得到了这些结果:
Postgres (1个CPU 4个ram, ssd) | Postgres (16 CPU 64 ram, ssd) | BigQuery | ||||
聚合 | 非聚合 | 聚合 | 非聚合 | 聚合 | 非聚合 | |
查询1(按年统计的美国人口) | 1.3s | 0.96s | 0.87s | 0.81s | 2.8s | 2.4s |
查询2(2019年按国家划分的人口) | 1.1s | 0.88s | 0.87s | 0.78s | 1.7s | 2.6s |
查询3(按年龄排列的最古老的5个国家) | 34.9s | 35.6s | 30.8s | 31.4s | 15.6s | 17.2s |
问题4(男女人口差异最大的前5个国家) | 16.2s | 15.6s | 14.8s | 14.5s | 4.3s | 4.6s |
查询5(各国年龄中位数,年) | 45.6s | 45.1s | 38.8s | 40.8s | 15.4s | 18s |
查询6(每年“垂死”的前5个国家) | 3.3s | 4.0s | 3.0s | 3.3s | 4.6s | 6.5s |
让我用柱状图显示查询#1和查询#5的结果.
注意: Postgres数据库位于美国的服务器上, 我在欧洲工作, 所以在Postgres传输数据时有额外的延迟.
根据我得到的结果,我得出了以下结论:
位置
表大约有400行 年龄_groups
与在位于一个表中的聚合数据下运行查询相比,100行是否没有产生巨大的差异. 也, 我发现对于运行1到2秒的查询, 使用内部连接的查询速度更快, 但是对于长时间运行的查询, 情况不同了.现在,让我们回到本文讨论的核心问题: 什么时候应该使用谷歌BigQuery? 根据我的结论,我建议在满足以下条件时使用BigQuery:
最后,再多说几句在实际生活中使用BigQuery的话. 在我们的实际项目中, 报告的数据每周或每月都在变化, 这样我们就可以手动将数据上传到BigQuery. 然而, 如果您的数据频繁更改, 在关系数据库和BigQuery之间同步数据可能没有那么简单, 这是一个值得记住的警告.
您可以在GCloud下使用BigQuery web控制台.
您可以在GCloud (http://console)下使用BigQuery web控制台.云.谷歌.com/bigquery). 它包含查询输入. 您还可以使用它们的REST API来运行查询.
是的,BigQuery使用SQL. 您可以在官方文档(http://云)中查看详细信息.谷歌.com/bigquery/docs/reference/standard-sql/).
只有谷歌知道他们是如何使查询运行得如此之快的, 但基本的想法是他们使用几台机器来运行每一个查询(水平扩展).
数据集是BigQuery中组织表的容器. 它允许管理对表和视图的访问. 你可以在这里找到更多信息:http://cloud.Google.com/bigquery/docs/datasets-intro
BigQuery的标准SQL兼容SQL 2011.
世界级的文章,每周发一次.
世界级的文章,每周发一次.