BigQuery 向け JDBC ドライバーの比較
この記事のメトリクスは、2019年10月時点で利用可能な最新のドライバーを使用して測定したものです。
BigQuery は「Google が提供するフルマネージドでペタバイト規模、低コストのエンタープライズ分析用データウェアハウス」であり、データの保存とアクセスに堅牢で広く利用されている方法を提供しています。多くの企業にとって、Google BigQuery はクラウドベースの分析プラットフォームの第一選択肢です。BigQuery はクラウドベースであるため、データベース管理者は不要で、インフラストラクチャのメンテナンスも必要ありません。
この記事では、大規模なデータセットを扱う際の Google 提供の JDBC Driver for Google BigQuery1、競合他社の JDBC Driver for Google BigQuery、および CData Software の JDBC Driver for Google BigQuery2 の読み取り・書き込みパフォーマンスを比較します。CData ドライバーが、他のドライバーよりも 1.5 倍から 13 倍高速に大規模データセットを読み取り、他のドライバーでは完了できない100万行のインサートを迅速に実行できることをご紹介します。
データ
読み取りパフォーマンスの再現可能な比較を提供するため、公開されている bigquery-public-data プロジェクト3の new_york_taxi_trips データセットから tlc_yellow_trips_2018 テーブルをクエリしました。tlc_yellow_trips_2018 テーブルの詳細は以下のとおりです。
| テーブルサイズ | テーブルの行数 | カラム数 | ||
|---|---|---|---|---|
| 18.1 GB | 112,234,626 | 17 |
JDBC ドライバーの読み取りパフォーマンス
この調査の主な目的は、各ドライバーの相対的なパフォーマンスを比較することでした。これを実現するため、各 JDBC ドライバーで同じクエリセットを実行しました。LIMIT 句を使用して各クエリで返されるデータセットのサイズを変更しましたが、すべてのクエリで同じカラムをリクエストしています。
ベースクエリ
SELECT vendor_id, passenger_count, trip_distance, rate_code, store_and_fwd_flag, payment_type, fare_amount, extra, mta_tax, tip_amount, tolls_amount, imp_surcharge, total_amount, pickup_location_id, dropoff_location_id FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2018`
LIMIT 句によるクエリ
- LIMIT 100000
- LIMIT 1000000
- LIMIT 10000000
ドライバーをテストするため、基本的な Java アプリケーションを使用して BigQuery に接続し、上記のクエリを繰り返し実行しました。結果を読み取り、各行の各カラムに対して(データ型に基づいた)新しい変数に格納しました。以下のチャートでは、V2 REST API とプレリリースの Storage API の2つの API を使用した比較を示しています(注:競合他社のドライバーは Storage API をサポートしていません)。下記のチャートに表示されている時間は、各クエリの平均時間(秒単位)です。
REST API を使用したデータクエリ
| ドライバー別クエリ時間(秒) | |||
|---|---|---|---|
| クエリ | CData JDBC | Google JDBC | 競合他社 JDBC |
| 1 (100,000 行) | 9.96 (+20%) | 11.89 | 12.37 |
| 2 (1,000,000 行) | 99.56 (+11%) | 110.40 | 111.04 |
| 3 (10,000,000 行) | 971.22 (+15%) | 1,114.76 | 1,074.95 |
結果から分かるように、CData ドライバーは REST API を使用した場合、他のドライバーよりも一貫して優れたパフォーマンスを発揮し、最大 24% 高速に結果を取得・処理しました。
Storage API を使用したデータクエリ
Storage API でのテストでは、サンプルデータセット内のすべてのデータに対する追加クエリを実行しました。
| ドライバー別クエリ時間(秒) | ||
|---|---|---|
| クエリ | CData JDBC | Google JDBC |
| 1 (100,000 行) | 3.64 (+126%) | 8.21 |
| 2 (1,000,000 行) | 10.06 (+90%) | 19.16 |
| 3 (10,000,000 行) | 82.62 (+54%) | 127.51 |
| 4 (112,234,626 行) | 911.39 (+49%) | 1,355.37 |
結果から分かるように、CData ドライバーは Storage API の高スループット機能を活用して、最大規模のデータセットでも Google ドライバーより 1.5 倍高速に取得・処理できます。
JDBC ドライバーのリソース使用量
JDBC ドライバーの読み取りパフォーマンスをテストする際、クライアント側のリソース使用量(特にメモリと CPU 使用率)も測定しました。以下のチャートは、サンプル Java プログラムを実行し、Java VisualVM を使用して CPU とメモリ使用率をキャプチャして取得したものです。Java バージョン 12 アップデート 211 を使用し、最大ヒープサイズは 4.27 GB に設定しました。
この比較では、V2 REST API に対して1,000万行のクエリを実行しました。
* ヒープグラフのスケールが変更されていることにご注意ください。
CData ドライバーは最初の数分間は平均約 700 MB のヒープ使用量で、その後残りの時間は約 250 MB を使用します。CPU 使用率グラフから、CData ドライバーが一貫して利用可能な CPU の約 6% から 7% を使用し、データが返されるのと同じ速さで一貫してデータを処理していることが分かります。
Google ドライバーは平均約 700 MB のヒープ使用量で、CData ドライバーとは異なり、実行時間のほとんどで高いヒープ使用量を維持し、実行の最後の4分の1で約 350 MB に低下します。Google ドライバーは実行時間全体を通じて利用可能な CPU の約 5% を使用します。
競合他社ドライバーは平均約 70 MB のヒープ使用量ですが、(CData および Google ドライバーと比較して)ヒープ使用量が比較的不安定です。競合他社ドライバーは実行時間全体を通じて利用可能な CPU の 5% 未満を使用します。
100万行チャレンジ再訪:3.5倍高速化
2017年10月に、CData JDBC ドライバーで100万行をインサートするタスク(Google ドライバーでは実行できなかったタスク)を実施しました。その後のドライバーのアップデートにより書き込み速度も向上し、現在は平均 5 分 47 秒でデータをインサートできます(各行に 19 カラム)。これにより、新しい CData JDBC ドライバーは以前よりも 3.5 倍以上高速にインサートを実行できるようになりました。
一方、Google ドライバーも競合他社ドライバーも、高パフォーマンスの INSERT ステートメントを実行できません。これらのドライバーは大規模なデータ取り込みメカニズムを実装していません。少数の INSERT ステートメントは実行できますが、大規模なデータセットをロードしようとすると、BigQuery Data Manipulation Language のレート制限に達してしまいます。1
nyc_tlc.yellow 公開データセット3の trips テーブルのコピーに行を追加するため、以前と同じシンプルな Java プログラムを使用しました。テストでは、10,000 行ずつ 100 バッチでデータをインサートしました。
サンプルコード
//one batch
Connection connection = DriverManager.getConnection("jdbc:googlebigquery:InitiateOAuth=GETANDREFRESH;QueryPassthrough=false;ProjectId=" + projectId + ";DatasetId=" + datasetId + ";Timeout=240;UseLegacySQL=false;");
String cmd = "INSERT INTO TestDataset.nyc_yellow_trips_copy (vendor_id, pickup_datetime, dropoff_datetime, pickup_longitude, pickup_latitude, dropoff_longitude, dropoff_latitude, rate_code, passenger_count, trip_distance, payment_type, fare_amount, extra, mta_tax, imp_surcharge, tip_amount, tolls_amount, total_amount, store_and_fwd_flag) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
PreparedStatement pstmt = connection.prepareStatement(cmd);
for (int row = 0; row < rows.length; row++){
String[] line = rows[row].split(",");
for (int i = 0 ; i < line.length; i++) {
//add parameters based on datatype
if ( (i < 3) || (i ==7) || (i==10) || (i==18) ) {
pstmt.setString(i + 1, line[i]);
} else if (i == 8) {
pstmt.setInt(i+1, Integer.parseInt(line[i]));
} else {
pstmt.setDouble(i+1, Double.parseDouble(line[i]));
}
}
pstmt.addBatch();
}
int[] affected = pstmt.executeBatch();
結果
| 行数 | カラム数 | 時間(秒) |
|---|---|---|
| 1,000,000 | 19(混合データ型) | 346.64 |
まとめ
CData ドライバーのパフォーマンスは前回の比較から向上しており、Google 提供ドライバーや競合他社ドライバーと比較して、大規模データセットのクエリにおいて引き続き優れた性能を発揮しています。利用可能なクライアントリソースをより効率的に活用し、最大規模のデータセットを 54% 高速に処理してデータの読み取りと処理を可能な限り迅速に行います。
データのインサートに関しては、CData ドライバーは大規模データセットを迅速にインサートする能力において他に類を見ません。前回の記事では、100万行を約 20 分でインサートできました。現在では、同じタスクを 6 分未満で完了できます。
当社の開発者は、Google から返される結果の処理においてパフォーマンスを最適化するために尽力してきました。その結果、ドライバーはウェブトラフィックとサーバー処理時間によってのみ制限されているように見えます。BigQuery の書き込み機能を最大限に活用するための同様の取り組みも行われており、CData ドライバーは Google BigQuery への読み取りと書き込みの両方において最適なドライバーとなっています。


