まず第一に、実行するクエリのタイプは非常に非効率的です。今のところ(Spark 1.5.0 *)このように結合を実行するには、クエリを実行するたびに両方のテーブルをシャッフル/ハッシュパーティション化する必要があります。 users
の場合は問題ありません user_id = 123
のテーブル 述語はプッシュダウンされている可能性が高いですが、それでもuser_address
で完全なシャッフルが必要です 。
さらに、テーブルが登録されているだけでキャッシュされていない場合、このクエリを実行するたびにuser_address
全体がフェッチされます。 MySQLからSparkへのテーブル。
アプリケーションにSparkを使用する理由は明確ではありませんが、単一のマシンセットアップ、小さなデータ、およびクエリの種類から、Sparkはここでは適切ではないことがわかります。
一般的に、アプリケーションロジックが単一のレコードアクセスを必要とする場合、SparkSQLはうまく機能しません。これは、OLTPデータベースの代替としてではなく、分析クエリ用に設計されています。
単一のテーブル/データフレームがはるかに小さい場合は、ブロードキャストを試すことができます。
import org.apache.spark.sql.DataFrame
import org.apache.spark.sql.functions.broadcast
val user: DataFrame = ???
val user_address: DataFrame = ???
val userFiltered = user.where(???)
user_addresses.join(
broadcast(userFiltered), $"address_id" === $"user_address_id")
*これは、Spark1.6.0で