1.为ä»ä¹sparkSQL
2.SparkSQL源码分析-05-SparkSQL的源码join处理
3.spark sql源码系列 | json_tuple一定比 get_json_object更高效吗?
4.spark sql源码系列 | with as 语句真的会把查询的数据存内存嘛?
5.SPARK-38864 - Spark支持unpivot源码分析
为ä»ä¹sparkSQL
SharkåsparkSQL ä½æ¯ï¼éçSparkçåå±ï¼å ¶ä¸sparkSQLä½ä¸ºSparkçæçä¸å继ç»åå±ï¼èä¸ååéäºhiveï¼åªæ¯å ¼å®¹hiveï¼èhive on sparkæ¯ä¸ä¸ªhiveçåå±è®¡åï¼è¯¥è®¡åå°sparkä½ä¸ºhiveçåºå±å¼æä¹ä¸ï¼ä¹å°±æ¯è¯´ï¼hiveå°ä¸ååéäºä¸ä¸ªå¼æï¼å¯ä»¥éç¨map-reduceãTezãsparkçå¼æã
ããShark为äºå®ç°Hiveå ¼å®¹ï¼å¨HQLæ¹é¢éç¨äºHiveä¸HQLç解æãé»è¾æ§è¡è®¡åç¿»è¯ãæ§è¡è®¡åä¼åçé»è¾ï¼å¯ä»¥è¿ä¼¼è®¤ä¸ºä» å°ç©çæ§è¡è®¡åä»MRä½ä¸æ¿æ¢æäºSparkä½ä¸ï¼è¾ 以å ååå¼åå¨çåç§åHiveå ³ç³»ä¸å¤§çä¼åï¼ï¼åæ¶è¿ä¾èµHive MetastoreåHive SerDeï¼ç¨äºå ¼å®¹ç°æçåç§Hiveåå¨æ ¼å¼ï¼ãè¿ä¸çç¥å¯¼è´äºä¸¤ä¸ªé®é¢ï¼ç¬¬ä¸æ¯æ§è¡è®¡åä¼åå®å ¨ä¾èµäºHiveï¼ä¸æ¹ä¾¿æ·»å æ°çä¼åçç¥ï¼äºæ¯å 为MRæ¯è¿ç¨çº§å¹¶è¡ï¼å代ç çæ¶åä¸æ¯å¾æ³¨æ线ç¨å®å ¨é®é¢ï¼å¯¼è´Sharkä¸å¾ä¸ä½¿ç¨å¦å¤ä¸å¥ç¬ç«ç»´æ¤çæäºè¡¥ä¸çHiveæºç åæ¯ï¼è³äºä¸ºä½ç¸å ³ä¿®æ¹æ²¡æå并å°Hive主线ï¼æä¹ä¸å¤ªæ¸ æ¥ï¼ã
ããæ¤å¤ï¼é¤äºå ¼å®¹HQLãå éç°æHiveæ°æ®çæ¥è¯¢åæ以å¤ï¼Spark SQLè¿æ¯æç´æ¥å¯¹åçRDD对象è¿è¡å ³ç³»æ¥è¯¢ãåæ¶ï¼é¤äºHQL以å¤ï¼Spark SQLè¿å 建äºä¸ä¸ªç²¾ç®çSQL parserï¼ä»¥åä¸å¥Scala DSLãä¹å°±æ¯è¯´ï¼å¦æåªæ¯ä½¿ç¨Spark SQLå 建çSQLæ¹è¨æScala DSL对åçRDD对象è¿è¡å ³ç³»æ¥è¯¢ï¼ç¨æ·å¨å¼åSparkåºç¨æ¶å®å ¨ä¸éè¦ä¾èµHiveçä»»ä½ä¸è¥¿ã
SparkSQL源码分析--SparkSQL的join处理
SparkSQL的join处理策略多样,针对不同场景各有优劣。源码首先,源码map join适用于小表广播至worker节点,源码提升性能,源码但大表可能导致OOM。源码技师上门小程序源码shuffle hash join则对大表进行分区和排序,源码效率高但内存密集。源码默认策略通过sort merge join,源码对大表进行分区排序,源码避免内存问题,源码但需预先排序。源码
当常规策略不可用时,源码会考虑等值或不等值join的源码广播nested loop join,适用于特定条件的源码right或left outer join。笛卡尔积join在无指定key时使用,仅限inner join。伪转转源码
SparkPlan中的Join子节点与策略紧密相关,如在等值连接时,根据hint选择Broadcast hash join、Shuffle sort merge join或shuffle hash join。没有hint时,依据表大小、join类型和排序情况自动选择。
非等值连接时,hint会引导使用broadcast nested loop join或Cartesian product join,无hint时则依据表大小和连接类型来决定。
在特殊情况下,如NotInSubquery,仍可能选择Broadcast hash join。总的来说,SparkSQL的join策略灵活多变,旨在根据具体场景提供最优的大巴票源码执行效率和资源利用率。
spark sql源码系列 | json_tuple一定比 get_json_object更高效吗?
对比json_tuple和get_json_object,网上普遍认为json_tuple效率更高。理由是json_tuple仅需解析一次json数据,而get_json_object需多次解析。实际操作中,get_json_object在解析json字符串到jsonObject阶段仅执行一次,而非多次解析。从执行计划角度看,get_json_object更为简洁,而json_tuple涉及udtf函数,其执行计划更为繁重。功能多样性上,get_json_object支持更丰富的路径处理,如正则匹配、嵌套、多层取值等,付费摄影源码而json_tuple仅能解析第一层key。在实际使用时,无需盲从效率结论,根据具体需求选择。确保json数据不过长过大,无论使用哪种方法,效率都不会理想。正确理解并合理运用这些函数,对于优化查询性能至关重要。
spark sql源码系列 | with as 语句真的会把查询的数据存内存嘛?
在探讨 Spark SQL 中 with...as 语句是否真的会把查询的数据存入内存之前,我们需要理清几个关键点。首先,网上诸多博客常常提及 with...as 语句会将数据存放于内存中,来提升性能。那么,实际情况究竟如何呢?
让我们以 hive-sql 的轻流源码视角来解答这一问题。在 hive 中,有一个名为 `hive.optimize.cte.materialize.threshold` 的参数。默认情况下,其值为 -1,代表关闭。当值大于 0 时(如设置为 2),with...as 语句生成的表将在被引用次数达到设定值后物化,从而确保 with...as 语句仅执行一次,进而提高效率。
接下来,我们通过具体测试来验证上述结论。在不调整该参数的情况下,执行计划显示 test 表被读取了两次。此时,我们将参数调整为 `set hive.optimize.cte.materialize.threshold=1`,执行计划显示了 test 表被物化的情况,表明查询结果已被缓存。
转而观察 Spark SQL 端,我们并未发现相关优化参数。Spark 对 with...as 的操作相对较少,在源码层面,通过获取元数据时所做的参数判断(如阈值与 cte 引用次数),我们可以发现 Spark 在这个逻辑上并未提供明确的优化机制,来专门针对 with...as 语句进行高效管理。
综上所述,通过与 hive-sql 的对比以及深入源码分析,我们得出了 with...as 语句在 Spark SQL 中是否把数据存入内存的结论,答案并不是绝对的。关键在于是否通过参数调整来物化结果,以及 Spark 在自身框架层面并未提供特定优化策略来针对 with...as 语句进行内存管理。因此,正确使用 with...as 语句并结合具体业务场景,灵活调整优化参数策略,是实现性能提升的关键。
SPARK- - Spark支持unpivot源码分析
unpivot是数据库系统中用于列转行的内置函数,如SQL SERVER, Oracle等。以数据集tb1为例,每个数字代表某个人在某个学科的成绩。若要将此表扩展为三元组,可使用union实现。但随列数增加,SQL语句变长。许多SQL引擎提供内置函数unpivot简化此过程。unpivot使用时需指定保留列、进行转行的列、新列名及值列名。
SPARK从SPARK-版本开始支持DataSet的unpivot函数,逐步扩展至pyspark与SQL。在Dataset API中,ids为要保留的Column数组,Column类提供了从String构造Column的隐式转换,方便使用。利用此API,可通过unpivot函数将数据集转换为所需的三元组。values表示转行列,variableColumnName为新列名,valueColumnName为值列名。
Analyser阶段解析unpivot算子,将逻辑执行计划转化为物理执行计划。当用户开启hive catalog,SPARK SQL根据表名和metastore URL查找表元数据,转化为Hive相关逻辑执行计划。物理执行计划如BroadcastHashJoinExec,表示具体的执行策略。规则ResolveUnpivot将包含unpivot的算子转换为Expand算子,在物理执行计划阶段执行。此转换由开发者自定义规则完成,通过遍历逻辑执行计划树,根据节点类型及状态进行不同处理。
unpivot函数实现过程中,首先将原始数据集投影为包含ids、variableColumnName、valueColumnName的列,实现语义转换。随后,通过map函数处理values列,构建新的行数据,最终返回Expand算子。在物理执行计划阶段,Expand算子将数据转换为所需形式,实现unpivot功能。
综上所述,SPARK内置函数unpivot的实现通过解析列参数,组装Expand算子完成,为用户提供简便的列转行功能。通过理解此过程,可深入掌握SPARK SQL的开发原理与内在机制。