<p>所以我研究了一下代码试图弄清楚到底发生了什么。似乎<code>sqlContext.createDataFrame</code>确实没有尝试根据数据设置合理的参数值。在</p>
<p><strong>为什么要执行2000个任务?</strong></p>
<p>Spark使用2000个任务,因为我的数据框有2000个分区。(尽管分区比行多似乎是一派胡言。)</p>
<p>具体表现在:</p>
<pre><code>>>> df.rdd.getNumPartitions()
2000
</code></pre>
<p><strong>为什么数据帧有2000个分区?</strong></p>
<p>发生这种情况是因为<code>sqlContext.createDataFrame</code>最终使用默认的分区数(在我的例子中是2000),而不管数据是如何组织的或它有多少行。在</p>
<p>代码跟踪如下。在</p>
<p>在<code>sql/context.py</code>中,<code>sqlContext.createDataFrame</code>函数调用(在本例中):</p>
^{pr2}$
<p>反过来又叫:</p>
<pre><code>return self._sc.parallelize(data), schema
</code></pre>
<p>并且<code>sqlContext.parallelize</code>函数在<code>context.py</code>中定义:</p>
<pre><code>numSlices = int(numSlices) if numSlices is not None else self.defaultParallelism
</code></pre>
<p>不检查行数,也不可能指定<code>sqlContext.createDataFrame</code>中的片数。在</p>
<p><strong>如何更改数据帧有多少个分区?</strong></p>
<p>使用<code>DataFrame.coalesce</code>。在</p>
<pre><code>>>> smdf = df.coalesce(1)
>>> smdf.rdd.getNumPartitions()
1
>>> smdf.explain()
== Physical Plan ==
Coalesce 1
+- Scan ExistingRDD[a#0L,b#1L]
>>> smdf.collect()
[Row(a=1, b=2)]
</code></pre>