大数据SQL优化:原理与实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.4 为什么要调优

在深入了解了大数据生态使用SQL作为统一查询语言的优势和局限性后,我们深知编写并运行一段高效且稳定的SQL代码并非易事,同样的统计需求,要面对不同的开发人员、不同的数据集、不同的执行引擎,甚至随着业务量增加以及业务复杂度的加深,所消耗的资源和运行时长都是截然不同的。因此,为了消除这些变量带来的影响,必须提高任务的稳定性和时效性,这就需要对SQL进行调整和优化。

1.4.1 降本提效

所谓降本提效,降的可以是资源成本,例如执行任务时的计算资源、存储开销等,也可以是人力成本,例如同样的需求或查询,可以用更少的人天来完成。同理,提效提升的可以是计算资源的利用率,也可以是开发人员的开发效率。数据源自业务,也期望能够赋能业务甚至驱动业务,毫无疑问,时间更短、产出更快、开销更少的数据应用或查询,更符合使用方或者业务方的要求。

而SQL查询作为许多应用程序的核心,其性能直接影响到用户体验和系统成本。不经优化的查询可能导致计算和存储资源的浪费、响应时间延迟以及系统不稳定性的增加。例如图1-3中监控订单表每日增量Binlog统计分布的看板。

如图1-4所示,约24s才将数据全部查询、加载完毕。对于业务方或使用方而言,这是难以接受和容忍的。

报表的数据源是ClickHouse,经过排查,我们发现是未设置索引所导致的慢查询问题。如图1-5所示,优化后的查询耗时从24.39s降低至850ms,查询体验大大改观。

图1-3 统计分布的看板示例

图1-4 未加索引前接口读取数据耗时

随着互联网大数据的兴起和数据量的爆炸式增加,系统的响应速度成为目前各类数据应用需要解决的最主要的问题之一。毫无疑问,高质量的SQL语句能够提升系统的可用性。在现在日新月异的时代,更稳健的数据应用、业务系统和更加高效的数据产出,使得业务决策快人一步,从而产生截然不同的结果。

图1-5 添加索引后接口读取数据耗时

1.4.2 知其然并知其所以然

在实际工作中,数据仓库、非平台功能的数据开发以及数据分析岗位的大部分工作内容都是建表或者用SQL将数据接入、导出,再根据业务需求产出数据报表或数据指标。正因为如此,我们被称为“表哥”“表姐”“SQL Boy”“茶树菇(查数据的小姑娘)”,连职位也会被人戏称为“临时取数员”。时间长了,难免有些人会对自己的工作产生疑问,怀疑自己的工作是否有意义,怀疑自己的发展前景是什么,以及思考怎么才能不做工具人。

诚然,SQL极低的使用门槛带来了极大的便捷性和受众群体。但也必须承认,正是因为其易用性,导致除了底层开发和DBA外,大多数人对SQL和引擎没有一个良好的认知,或者说了解深度不够。这导致的问题无外乎以下几类。

❑ 不理解什么是调优,也不知道该如何调优。SQL任务跑不出来或跑不动的时候,往往只能够采用加内存、加并行度等“水多加面,面多加水”的笨方法,从而导致了资源的无端浪费。

❑ 极端的SQL查询或者ETL任务会严重影响整个系统的稳定性甚至造成宕机。例如不限制分区的全表扫描、笛卡儿积、全外连接等。

❑ 在项目或团队成立初期,时间紧、任务重,需求倒排,来不及思考可扩展性和复用性,往往都会先交付了事,再加上开发人员的专业素养参差不齐、人员流失等各种因素的影响,最终就会演变成饱受诟病的“祖传”代码难以维护和迭代

总的来说,就是“只得其形,未得其意”。工作不能只浮于表面,要清楚地了解背后的原理,才能对需求或出现的问题有准确判断,不至于被他人所左右。要清楚地了解使用场景、存在的瓶颈或局限性,才能做到游刃有余、有的放矢。

下面将正式开始剖析在实际工作中,在电商、内容、支付等业务场景和领域下,关于数据分析、数据仓库建设,以及在流批一体探索的客观问题和这些问题出现的原因,并提供解决这些问题的实际策略、最佳实践和案例研究,以帮助读者更好地理解和应对这些问题。

正如前文所述,大数据引擎自优化的理念和经验均来自关系型数据库,因此在深度剖析的理论部分,笔者不刻意区分或强调两者的差异。理论不仅适用于大数据引擎,同样适用于关系型数据库,例如子查询展开(Subquery Unnesting)和去重迁徙(Distinct Placement)。而在具体实践中,例如在离线批处理的计算场景中,主要使用Apache Spark(2.x版本)来讲解案例;在实时流计算的场景中,主要使用Apache Flink(1.13.x版本)来讲解案例。