web-dev-qa-db-ja.com

spark述語プッシュダウンはJDBCで機能しますか?

this によると

Catalystは、述語プッシュダウンなどの論理最適化を適用します。オプティマイザーは、フィルター述部をデータソースにプッシュプッシュできるため、物理的な実行で無関係なデータをスキップできます。

Sparkは、データソースへの述語のプッシュダウンをサポートしています。この機能はJDBCでも利用できますか/期待されていますか?

(DBログを調べると、現時点ではデフォルトの動作ではないことがわかります-後でsparkフィルターによって制限されている場合でも)完全なクエリがDBに渡されます)

詳細

実行中Spark 1.5とPostgreSQL 9.4

コードスニペット:

from pyspark import SQLContext, SparkContext, Row, SparkConf
from data_access.data_access_db import REMOTE_CONNECTION

sc = SparkContext()
sqlContext = SQLContext(sc)

url = 'jdbc:postgresql://{Host}/{database}?user={user}&password={password}'.format(**REMOTE_CONNECTION)
sql = "dummy"

df = sqlContext.read.jdbc(url=url, table=sql)
df = df.limit(1)
df.show()

SQLトレース:

< 2015-09-15 07:11:37.718 EDT >LOG:  execute <unnamed>: SET extra_float_digits = 3                                                                                                                      
< 2015-09-15 07:11:37.771 EDT >LOG:  execute <unnamed>: SELECT * FROM dummy WHERE 1=0                                                                                                                   
< 2015-09-15 07:11:37.830 EDT >LOG:  execute <unnamed>: SELECT c.oid, a.attnum, a.attname, c.relname, n.nspname, a.attnotnull OR (t.typtype = 'd' AND t.typnotnull), pg_catalog.pg_get_expr(d.adbin, d.a
drelid) LIKE '%nextval(%' FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid) JOIN pg_catalog.pg_attribute a ON (c.oid = a.attrelid) JOIN pg_catalog.pg_type t ON (a.a
tttypid = t.oid) LEFT JOIN pg_catalog.pg_attrdef d ON (d.adrelid = a.attrelid AND d.adnum = a.attnum) JOIN (SELECT 15218474 AS oid , 1 AS attnum UNION ALL SELECT 15218474, 3) vals ON (c.oid = vals.oid
 AND a.attnum = vals.attnum)                                                                                                                                                                            
< 2015-09-15 07:11:40.936 EDT >LOG:  execute <unnamed>: SET extra_float_digits = 3                                                                                                                      
< 2015-09-15 07:11:40.964 EDT >LOG:  execute <unnamed>: SELECT "id","name" FROM dummy                                                                                                                   

最後の選択にはlimit 1句が含まれると思いますが、含まれていません

23
Ophir Yoktan

Spark DataFrameは、JDBCソースを使用した述語プッシュダウンをサポートしていますが、厳密なSQLの意味でpredicateという用語が使用されています。つまり、WHERE句のみを対象としています。さらに、論理結合(INORは怖い)と単純な述語に限定されているようです。

制限、カウント、順序、グループ、条件など、その他すべては、Spark=側で処理されます。SOですでにカバーされている1つの警告は、df.count()またはsqlContext.sql("SELECT COUNT(*) FROM df")SELECT 1 FROM dfに変換され、Sparkを使用した実質的なデータ転送と処理の両方が必要です。

それは失われた原因であるということですか?ではない正確に。 table引数として任意のサブクエリを使用することが可能です。述語プッシュダウンほど便利ではありませんが、それ以外はかなりうまく機能します。

n = ... # Number of rows to take
sql = "(SELECT * FROM dummy LIMIT {0}) AS tmp".format(int(n))
df = sqlContext.read.jdbc(url=url, table=sql)

この動作は、Data Source API v2の準備が整ったら、将来改善される可能性があります。

23
zero323