MySQL 向け JDBC ドライバーのパフォーマンス比較



MySQL は「世界で最も人気のあるオープンソースデータベース」であり、データの保存とアクセスに広く利用されている堅牢なソリューションです。実際、多くのクラウドデータベースが他の選択肢よりも MySQL インターフェースを採用しています。MySQL データに他のアプリケーションから接続するためのネイティブなオープンソースドライバーも数多く提供されています。

準備

この記事では、MySQL のネイティブオープンソース JDBC ドライバー(Connector/J1)、MariaDB(人気の MySQL フォーク)の Connector/J2、そして CData のライセンス版 JDBC ドライバー(JDBC Driver for JDBC 20163)を比較します。ベンチマークを提供するため、テストマシンに MySQL Server 5.7 をインストールし、比較的大規模なデータセットをデータベースに挿入しました。

テストマシンの仕様は以下のとおりです:
オペレーティングシステム:Windows 7 Ultimate, SP1
プロセッサ:Intel® CoreTM i3-2120 CPU @ 3.30GHz
メモリ(RAM):8.00 GB
システムタイプ:64 ビットオペレーティングシステム

ドライバーを横並びで比較しているため、マシン自体のパフォーマンスは比較的重要ではありません。重要なのは、ドライバー同士の相対的な比較です。

補足として、他の商用 JDBC ドライバーも比較に含める予定でしたが、それらは MySQL Server の Community Edition への接続をサポートしていませんでした。

比較

比較を開始するにあたり、MySQL に新しいデータベースを作成し、以下に示す「restaurant」というテーブルを作成しました:

+-----------------+---------------+------+-----+---------+-------+
| Field           | Type          | Null | Key | Default | Extra |
+-----------------+---------------+------+-----+---------+-------+
| _id             | int(10)       | NO   | PRI |         |       |
| grades          | varchar(2000) | YES  |     | NULL    |       |
| address_street  | varchar(255)  | YES  |     | NULL    |       |
| address_zipcode | int(11)       | YES  |     | NULL    |       |
| name            | varchar(255)  | YES  |     | NULL    |       |
| address_coord   | varchar(255)  | YES  |     | NULL    |       |
| building        | varchar(127)  | YES  |     | NULL    |       |
| restaurant_id   | bigint(20)    | NO   |     | NULL    |       |
| borough         | varchar(255)  | YES  |     | NULL    |       |
| cuisine         | varchar(255)  | YES  |     | NULL    |       |
| avg_score       | double        | YES  |     | NULL    |       |
+-----------------+---------------+------+-----+---------+-------+

データセットは 1,546,899 行のデータ(3.45 GB)で構成されており、各行にはレストランに関する情報が含まれています。

この調査の主な目的は、ドライバー間の相対的なパフォーマンスを比較することでした。これを実現するため、各ドライバーで同じ 4 つのクエリを実行しました。クエリは以下のとおりです:

  1. [SELECT * FROM restaurant]
  2. [SELECT _id, grades, avg_score, name, cuisine FROM restaurant]
  3. [SELECT cuisine, AVG(avg_score) FROM restaurant GROUP BY cuisine]
  4. *JDBC メタデータリクエスト*
上記のクエリは結果の件数がそれぞれ異なり、各ドライバーが大規模および小規模な結果セットを処理する能力を示します。

結果

各ドライバーについて、データベースへの接続を確立し、4 つのクエリをすべて連続して実行しました。この操作をドライバーごとに 50 回実行し、各クエリの 50 回の実行の平均実行時間を算出しました。結果は以下の表に示します。

ドライバー別クエリ時間(ミリ秒)
クエリCDataMySQLMariaDB
19786.43114518.18222582.566
28536.83812843.32915582.370
37841.8127602.339 7571.693
44.718 4.288 2.056

結果からわかるように、CData ドライバーは大規模な結果セットを扱う際にネイティブの MySQL ドライバーと MariaDB を大幅に上回り、他のクエリでも同等のパフォーマンスを示しました。

「SELECT * ...」クエリでは、1 億 7,000 万以上のデータポイント(150 万行以上 × 11 カラム)を読み取る必要があり、CData ドライバーは MySQL ドライバーの約 67% の時間で結果を読み取ることができました。

2 番目のクエリ(「SELECT _id, grades, avg_score, ...」)では約 770 万のデータポイントを読み取る必要があり、CData ドライバーは MySQL ドライバーの約 66% の時間で結果を読み取ることができました。

ここで注目すべき点として、1 番目と 2 番目のクエリにおける CData ドライバーのパフォーマンスは、MySQL ドライバーや MariaDB ドライバーと比較して大幅に類似しています。これは、CData ドライバーが使用する時間の大部分がネットワーク通信時間とサーバー処理時間に基づいており、結果の処理にかかる時間ではないことを示しています。

3 番目のクエリ(「SELECT cuisine, AVG(avg_score) ...」)では 170 のデータポイント(「cuisine」の 85 種類のユニークな値から生じる 85 行 × 2 カラム)を処理する必要があり、各ドライバーのパフォーマンスはほぼ同じです。これは、結果の件数が少なく、MySQL Server が各グループの avg_score の平均を計算するのに時間がかかることに起因します。

MySQL ドライバーと MariaDB の両方が CData ドライバーを明らかに上回った唯一のケースは、テーブルのメタデータを読み取るタスクでした。パフォーマンスの差は大きく見えますが(CData ドライバーは MariaDB ドライバーの 2 倍以上の時間がかかります)、実際のパフォーマンス差は事実上気づかないレベルです(約 2.5 ミリ秒、まばたきにかかる時間の 100 分の 14)。

各クエリの平均実行時間を以下のチャートで比較しています:

結論

クエリの結果に基づき、CData ドライバーのパフォーマンスはネイティブの MySQL Connector/J および MariaDB Connector/J をはるかに上回ると結論づけることができます。CData の開発者は、結果セットの処理においてパフォーマンスを最大化するための印象的な作業を行っており、ネットワーク通信とサーバー処理時間のみが制約となっているようです。このパフォーマンスは、ドライバーが大量のデータを処理する必要がある場合に特に際立ちます。

参考文献

  1. https://dev.mysql.com/downloads/connector/j/
  2. https://downloads.mariadb.org/connector-java/
  3. https://jp.cdata.com/drivers/mysql/jdbc/
  4. http://bionumbers.hms.harvard.edu//bionumber.aspx?id=100706&ver=0