MySQLの基本的なSQLの評価順を日本語で表現してみる(1)

決め事として、

  • indexed_*** = インデックスが貼ってあるカラム
  • unindexed_*** = インデックスが貼ってないカラム

とする。

indexとは

MySQLのデータテーブルにもPostgreSQLと同じようなoidがレコードごとに存在し、indexとは、そのoidとカラムの値を対で持ったシンプルなテーブルみたいなものだと理解すればわかりやすい。
そのカラムだけを見て、どの行が該当するかを判断することができるため、検索負荷が非常に少なく済むのだ。

はじめに、シンプルなSQL

例えばこんなSQL。
SELECT COUNT(indexed_id) FROM sample_table WHERE indexed_column_1 = 1 AND unindex_column_2 > 2 AND indexed_column_3 = 3 ORDER BY indexed_id desc LIMIT 10;

どこにでもよくある文体だけど、これを日本語で表すと

  1. indexed_id のインデックスを参考に、実レコードの評価をする際のレコードの評価順を降順と定める
  2. インデックスを参考に indexed_column_1 = 1 を満たすレコードを全て特定する
  3. 上記までで特定した範囲で、最初に決めた評価順でunindex_column_2 > 2 を満たす実レコードを全て特定する
  4. 上記で抽出した実レコードから、インデックスを参考に indexed_column_3 = 3 の実レコードを全て抽出する
  5. 上記で抽出した実レコードから、最初に決めた評価順で先頭から探し、最大10件抽出する
  6. 特定したレコードのindexed_id の数を算出する

となる。

基礎条件:インデックスに乗ってないカラムのWHERE条件はできる限り後ろに

これを、こう書き換えると
SELECT COUNT(indexed_id) FROM sample_table WHERE indexed_column_1 = 1 AND indexed_column_3 = 3 AND unindex_column_2 > 2 ORDER BY indexed_id desc LIMIT 10;

こんな日本語になる。

  1. indexed_id のインデックスを参考に、実レコードの評価をする際のレコードの評価順を降順と定める
  2. 上記まででインデックスを参考に indexed_column_1 = 1 を満たすレコードを全て特定する
  3. 上記までで特定した範囲で、インデックスを参考に indexed_column_3 = 3 を満たすレコードを全て特定する
  4. 上記までで特定した範囲で、最初に決めた評価順でunindex_column_2 > 2 を満たすレコードを先頭から探し、最大10件特定する
  5. 特定したレコードのindexed_id の数を算出する

どちらが処理コストが少ないかは自明で、レコード数が多くなればなるほどその傾向は顕著になるのだ。

AWS AuroraとMySQLの比較

AWS

2015年09月のAWS ラスベガス re:Invent でRDS Auroraが東京リージョンに降りてきました。
うちのプロダクトでもRDS MySQLからのリプレースに向けて動き出しています。

話題になっている数字の根拠など含め、シンプルに、パフォーマンス的な違いをまとめました。

MySQLとAuroraの基本的な違い
  • MultiAZが違う(Auroraは、Managed MultiAZ的な感じ。MultiAZ構成は「3つのAvailability Zoneに2つずつのレプリケーションを保存する」としている。)
  • リードレプリカが違う(Auroraは1マスターに対し15のリードレプリカを持つことができる)
  • PIOPSの概念もManaged化されていて、自分で帯域予約設定をする、などの運用は不要になっている

MySQLの5倍のパフォーマンスとは?

「Amazon Aurora は、データベースワークロード用の SSD ベースの仮想化ストレージレイヤーとデータベースエンジンを完全に統合し、ストレージシステムに対する書き込みを削減し、ロックの競合を最小化し、データベースのプロセススレッドを排除することで、MySQL と比較して大幅に高いパフォーマンスを提供します。SysBench による r3.8xlarge インスタンスのテストの結果、Amazon Aurora は 500,000 セレクト/秒および 100,000 アップデート/秒のパフォーマンスを示しました。これは同じハードウェアで実行する MySQL の 5 倍のパフォーマンスです。このベンチマークとその再現方法の詳細な手順は、Amazon Aurora のパフォーマンスベンチマークに関するガイドに記載されています。」

引用「:https://aws.amazon.com/jp/rds/aurora/faqs/

Aurora向けのアプリケーションチューニングのポイント

Amazon Aurora は MySQL 5.6 と互換性を持つように設計されているため、既存の MySQL アプリケーションおよびツールを修正することなく実行できます。一方で、Amazon Aurora が MySQL よりも優れている領域の 1 つが、ワークロードの同時実行数が非常に多い場合です。Amazon Aurora でワークロードのスループットを最大化するには、多数のクエリを同時実行するようにアプリケーションを作成することをお勧めします。

引用「:https://aws.amazon.com/jp/rds/aurora/faqs/

レプリケーション構成

これが一番違うかも?Auroraはリードレプリカを作成してもストレージを共用するため、レプリケーションラグがかなり低いようです。

スクリーンショット 2015-10-13 11.38.55

Q. レプリカはどのくらいプライマリから遅れますか?
A. Amazon Aurora レプリカはプライマリと同じデータボリュームを共有しているため、実質的にレプリケーションラグはありません。ラグは通常数十ミリ秒です。MySQL リードレプリカの場合、レプリケーションラグは変更率または適用率、およびネットワーク通信の遅延に応じて無制限に増大する可能性があります。ただし、通常の状況では数分のレプリケーションラグが一般的です。

引用「:https://aws.amazon.com/jp/rds/aurora/faqs/

商用DBの1/10のコスト

これは、商用DBが何を指しているのか不明ですが(おそらくはOracleやSQL Serverだと思う)実際のコストは以下のようになっています。
引用:RDS Auroraの料金:https://aws.amazon.com/jp/rds/aurora/pricing/
引用:RDS MySQLの料金:https://aws.amazon.com/jp/rds/mysql/pricing/

インスタンス料金

  • Aurora: db.r3.8xlarge($5.6/h)
  • MySQL:SingleAZ:db.r3.8xlarge($4.540/h)
  • MySQL:MultiAZ:db.r3.8xlarge($9.080/h)

ストレージ料金

  • Aurora:ストレージ料金($0.100 : GB あたり/月)I/O 料金($0.200 /100 万リクエスト)
  • MySQL:SingleAZ:General Purpose (SSD) Storage($0.138 : GB あたり/月)
  • MySQL:MultiAZ:General Purpose (SSD) Storage($0.276 : GB あたり/月)

まだ調べ切れてない懸念

このあたりはちゃんと保持されているのかな。。。
http://aws.amazon.com/jp/about-aws/whats-new/2015/01/06/amazon-rds-encryption-with-kms-mysql-postgresql/