Spark SQL执行Join查询时遭遇scala.MatchError问题求助
问题与解决建议
在Amazon AWS环境运行Spark 3.0.1版本,执行带CTE的Join查询时触发scala.MatchError。单独查询table1和table2可正常返回结果,但执行Join操作报错,调换关联表顺序也无法解决。
使用的查询语句
query = ''' WITH a1 AS ( SELECT val_in_min, val_date FROM table1 ), a2 AS ( SELECT val_in_sec, val_date FROM table2 ) SELECT a.val_in_min, a.val_date, b.val_in_sec FROM a1 a JOIN a2 b ON a.val_date=b.val_date ''' spark.sql(query).show()
样本数据
table1
| val_date | val_in_min |
|---|---|
| 2023-05-01 | 11.4833 |
| 2023-05-02 | 9.90000 |
table2
| val_date | val_in_sec |
|---|---|
| 2023-05-01 | 23 |
| 2023-05-02 | 26 |
错误信息
An error was encountered: An error occurred while calling o120.showString. : scala.MatchError: list#77341 [] (of class org.apache.spark.sql.catalyst.expressions.ListQuery) at org.apache.spark.sql.catalyst.optimizer.SizeBasedJoinReorder$.hasFilterPredicate(SizeBasedJoinReorder.scala:285) at scala.collection.LinearSeqOptimized.exists(LinearSeqOptimized.scala:95) at scala.collection.LinearSeqOptimized.exists$(LinearSeqOptimized.scala:92) at scala.collection.immutable.List.exists(List.scala:89) at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244) at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357) at py4j.Gateway.invoke(Gateway.java:282) at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132) at py4j.commands.CallCommand.execute(CallCommand.java:79) at py4j.GatewayConnection.run(GatewayConnection.java:238) at java.lang.Thread.run(Thread.java:750) Traceback (most recent call last): File "/mnt/yarn/usercache/appcache/application_1686133156822_0013/container_1686133156822_0013_01_000001/pyspark.zip/pyspark/sql/dataframe.py", line 441, in show print(self._jdf.showString(n, 20, vertical)) File "/mnt/yarn/usercache/appcache/application_1686133156822_0013/container_1686133156822_0013_01_000001/py4j-0.10.9-src.zip/py4j/java_gateway.py", line 1305, in __call__ answer, self.gateway_client, self.target_id, self.name) File "/mnt/yarn/usercache/appcache/application_1686133156822_0013/container_1686133156822_0013_01_000001/pyspark.zip/pyspark/sql/utils.py", line 128, in deco return f(*a, **kw) File "/mnt/yarn/usercache/appcache/application_1686133156822_0013/container_1686133156822_0013_01_000001/py4j-0.10.9-src.zip/py4j/protocol.py", line 328, in get_return_value format(target_id, ".", name), value) py4j.protocol.Py4JJavaError: An error occurred while calling o120.showString. : scala.MatchError: list#77341 [] (of class org.apache.spark.sql.catalyst.expressions.ListQuery) at org.apache.spark.sql.catalyst.optimizer.SizeBasedJoinReorder$.hasFilterPredicate(SizeBasedJoinReorder.scala:285) at org.apache.spark.sql.catalyst.optimizer.SizeBasedJoinReorder$.$anonfun$hasFilterPredicate$1(SizeBasedJoinReorder.scala:293) at org.apache.spark.sql.catalyst.optimizer.SizeBasedJoinReorder$.$anonfun$hasFilterPredicate$1$adapted(SizeBasedJoinReorder.scala:293) at scala.collection.LinearSeqOptimized.exists(LinearSeqOptimized.scala:95) at scala.collection.LinearSeqOptimized.exists$(LinearSeqOptimized.scala:92) at scala.collection.immutable.List.exists(List.scala:89)
解决建议
这是Spark 3.0.1版本中SizeBasedJoinReorder优化器的已知bug,可通过以下方式解决:
- 禁用该优化规则:在Spark配置中添加
spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.SizeBasedJoinReorder,禁用后查询可正常执行。 - 改写查询语句:去掉CTE结构,改用直接子查询的方式,例如:
SELECT a.val_in_min, a.val_date, b.val_in_sec FROM (SELECT val_in_min, val_date FROM table1) a JOIN (SELECT val_in_sec, val_date FROM table2) b ON a.val_date = b.val_date - 升级Spark版本:该bug在Spark 3.0.2及后续版本中已修复,升级到更高版本可彻底解决问题。
内容的提问来源于stack exchange,提问作者vvazza
相关产品推荐
相关产品推荐

