uj5u.com熱心網友回復:
對這兩個查詢運行解釋,這將向您顯示它們采用的不同路徑。他們都查看所有資料(我最初的回答是錯誤的)
Window 將所有資料發送到 1 個節點。在這種情況下,您還使用 where 子句,這意味著它使用 shuffle 來完成過濾。這似乎比 limit 用于大量專案的實作要快。由于資料量大,它可能更快。額外的 shuffle 對小型資料集有害,但如果在大型資料集上正確優化,有助于分散負載并減少所需時間。
== Physical Plan ==
*(2) Filter (isnotnull(row_number#66) && (row_number#66 <= 1000000000))
- Window [row_number() windowspecdefinition(date#61 ASC NULLS FIRST, specifiedwindowframe(RowFrame, unboundedpreceding$(), currentrow$())) AS row_number#66], [date#61 ASC NULLS FIRST]
- *(1) Sort [date#61 ASC NULLS FIRST], false, 0
- Exchange SinglePartition
- Scan hive default.table_persons [people#59, type#60, date#61], HiveTableRelation `default`.`table_persons`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [people#59, type#60, date#61]
“Order by”使用不同的實作,并且在使用“large take”時似乎表現不佳。它沒有使用盡可能多的隨機播放,但這似乎在有大量要回傳的專案時無法快速完成作業。
== Physical Plan ==
TakeOrderedAndProject(limit=100000000, orderBy=[date#61 ASC NULLS FIRST], output=[people#59,type#60,date#61])
- Scan hive default.table_persons [people#59, type#60, date#61], HiveTableRelation `default`.`table_persons`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [people#59, type#60, date#61]
順便說一句,對于大型傾斜資料集,通常添加 2 個額外的 shuffle,這實際上比沒有額外的 shuffle 花費的時間更少。(但同樣會增加處理小型資料集的時間。)
那么TakeOrderedAndProject實際上是做什么的呢?它對大型資料集使用磁盤上的資料并對其進行排序。(而不是在記憶體中排序)。
使用您的視窗,它確實會進行隨機播放,該隨機播放確實使用范圍對資料進行排序。有推論認為,進一步的排序是在記憶體中完成的,可以讓您在性能上進行權衡。(更新了以下推論的鏈接。)
這就是我認為你得到回報的地方。(我很想知道在現有視窗中添加限制是否會加快速度。)
從reddit 上的代碼片段和挖掘問題可以推斷出排序是在記憶體中完成的,如果需要,它會溢位到磁盤。
另一個我覺得提供了很多性能提升的部分是你使用了一個where子句。Take 從每個磁區中提取與limit子句中一樣多的專案。(參見上面的實作。)這樣做只是為了扔掉物品。 where不會拉回任何與過濾條件不匹配的專案。這種資料移動 [使用限制] 可能是您在limit.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/468351.html
標籤:阿帕奇火花 pyspark apache-spark-sql 火花窗函数
上一篇:如何更改地圖資料型別中的值
下一篇:如何渲染避免安全區域視圖?
