为了允许系统用户动态(通过应用程序Web UI)创建带有辅助数据的不同数据字典,我使用DataFrames并将它们公开为临时表,例如:
foreach ($array['OPMWebBlog'] as $item) {
echo $item['WebTitle'];
echo $item['WebBody'];
...
}
这些词典的数量仅受用户想象力和业务需求的限制。
此后,用户还创建不同的查询,这些查询可以使用基于先前定义的辅助数据的条件,例如SQL Seq("Italy", "France", "United States", "Spain").toDF("country").createOrReplaceTempView("big_countries")
Seq("Poland", "Hungary", "Spain").toDF("country").createOrReplaceTempView("medium_countries")
条件:
WHERE
这些查询的数量仅受用户想象力和业务需求的限制。
我现在最担心的是像Q1: country IN (FROM medium_countries)
Q2: (TRUE = ((country IN (FROM medium_countries)) AND (country IN (FROM big_countries))) AND EMAIL IS NOT NULL) AND phone = '+91-9111999998'
Q3: TRUE = ((country IN (FROM medium_countries)) AND (country IN (FROM big_countries))) AND EMAIL IS NOT NULL
......
Qn: name = 'Donald' AND email = 'donald@example.com' AND phone = '+1-2222222222'
根据系统设计,这里我不能使用显式country IN (FROM medium_countries)
,因此我只能使用子查询。因此,我有一个问题-这些辅助数据表的大小通常应该相对较小...我认为最坏情况下的几千行和这些表的总数-最坏情况下的几百行。考虑到这一点,这种方法是否会导致性能问题,是否存在可以优化流程的技术,例如将这些字典缓存在内存中等等?
已更新
现在我只能在Spark本地模式下对其进行测试
查询:
JOIN
执行计划:
country IN (FROM big_countries)
查询:
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---+
|plan |tag|
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---+
|== Physical Plan ==
*(1) Project [unique_id#27L]
+- *(1) BroadcastHashJoin [country#22], [country#3], LeftSemi, BuildRight
:- *(1) Project [country#22, unique_id#27L]
: +- LocalTableScan [name#19, email#20, phone#21, country#22, unique_id#27L]
+- BroadcastExchange HashedRelationBroadcastMode(List(input[0, string, true]))
+- LocalTableScan [country#3]|big|
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---+
执行计划:
TRUE = ((country IN (FROM medium_countries)) AND (country IN (FROM big_countries))) AND EMAIL IS NOT NULL
答案 0 :(得分:1)
我认为:
#? version_file
checkout
#? final_target
$0 version_file # Static dependency
version=$(get version from version_file)
$0 file_$version # Dynamic dependency
是在执行以下操作之后需要执行的操作:
CACHE TABLE tbl as in sql("CACHE TABLE tbl")
但当然要先进行较大的查询。
现在在SPARK中,默认情况下,上面关于“缓存”的声明现在很急,而不是偷懒。如手册所述,您不再需要手动触发缓存实现。也就是说,不再需要执行df.show或df.count。
一旦在内存中-在您明确刷新之前,不需要再次获取此数据,并且这里看起来好像没有过滤,而是只需加载所有有限的数据集一次即可。
不知道您的设计,但看着它,子查询应该没问题。尝试这种方法并查看物理计划。在传统的RDBMS中,这种有限的子查询(据我所知)也不会破坏交易。
您还可以看到,物理计划表明Catalyst Optimizer已将您的IN子查询优化/转换为JOIN,这对于较大的数据集而言是典型的性能改进。
因此,发生了将较小的表“广播”到执行者的工作节点的情况,从而也提高了性能。您可能不需要为广播设置任何限制,但是可以根据我的观察明确地设置此限制,但是可以接受的是,这不是必需的。