5.1. 最適化#
Mroongaはより速くレスポンスを返すためにいくつか最適化しています。
いくつかの最適化は ストレージモード でだけ有効です。
5.1.1. 必要なカラムだけ取得#
この最適化は ストレージモード でだけ有効です。
Groongaはカラム(列)ストアアーキテクチャーを採用しています。これは、1行の1つのカラムの値を取得するために、すべてのカラムの値を取得しなくてもよいということです。Groongaは必要なカラムの値だけを取得できます。
InnoDBとMyISAMはロー(行)ストアアーキテクチャーを採用しています。InnoDBとMyISAMは、1行の1つのカラムの値が必要な場合でもすべてのカラムの値を取得する必要があります。
SELECT
で必要なカラムだけを指定した場合、Mroongaは指定されたカラムの値だけを取得します。Mroongaは他のカラムの値を取得しません。
Mroongaは処理とI/Oを減らすことでより高速になります。
これがこの最適化です。
以下はこの最適化を説明するためのテーブル定義です。:
CREATE TABLE t1 (
c1 INT PRIMARY KEY AUTO_INCREMENT,
c2 INT,
c3 INT,
...
c11 VARCHAR(20),
c12 VARCHAR(20),
...
c20 DATETIME
) ENGINE=Mroonga DEFAULT CHARSET=utf8;
以下はこの最適化を説明するための SELECT
です。:
SELECT c1, c2, c11 FROM t1 WHERE c2 = XX AND c12 = "XXX";
このケースではMroongaは c1
、 c2
、 c11
、 c12
カラムの値だけを取得します。 c3
、 c4
、 ...、 c10
、 c13
、 ...、 c19
、c20
カラムの値は取得しません。
5.1.2. 行カウント#
この最適化は ストレージモード でだけ有効です。
MySQLは COUNT(*)
を処理する時、カラムの値が必要ないにも関わらず、ストレージエンジンモジュールにすべてのカラムの値を要求します。
この場合、Mroongaはカラムの値を取得しません。
Mroongaは処理とI/Oを減らすことでより高速になります。
これがこの最適化です。
以下はこの最適化を説明するための SELECT
です。:
SELECT COUNT(*) FROM t1 WHERE MATCH(c2) AGAINST("+keyword" IN BOOLEAN MODE);
この SELECT
は COUNT(*)
だけを取得し、 WHERE
の条件はインデックスだけで処理できます。この場合、Mroongaはこの最適化を使います。
この最適化が使われたかどうかは Mroonga_count_skip ステータス変数を参照するとわかります。:
mysql> SHOW STATUS LIKE 'Mroonga_count_skip';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| Mroonga_count_skip | 1 |
+--------------------+-------+
1 row in set (0.00 sec)
Mroonga_count_skip ステータス変数の値はMroongaがこの最適化を使うとインクリメントされます。
mroonga_enable_optimization に false
を指定するとこの最適化を無効にできます。
5.1.3. ORDER BY LIMIT
#
この最適化は ストレージモード と ラッパーモード 両方で有効です
MySQLは、ヒットレコード数が多くても、インデックスを使ってソート済みの結果を取得できるなら ORDER BY
と LIMIT
を少ないコストで処理できます。
MySQLは MATCH() AGAINST(IN NATURAL LANGUAGE MODE)
でこの処理を使えますが、 MATCH() AGAINST(IN BOOLEAN MODE)
では使えません。
これは、多くのレコードがマッチする MATCH() AGAINST(IN BOOLEAN MODE)
には時間がかかる可能性があるということです。
MroongaはGroongaを使って ORDER BY
と LIMIT
を処理し、MySQLには処理対象のレコードだけを返します。マッチレコード数が多いとき、MySQLで処理するよりもGroongaで処理する方が非常に高速です。
これがこの最適化です。
以下はこの最適化を説明するための SELECT
です。:
SELECT *
FROM t1
WHERE MATCH(c2) AGAINST("+keyword" IN BOOLEAN MODE)
ORDER BY c1 LIMIT 1;
この SELECT
は全文検索とソートをGroongaで実行し、MySQLには1件のレコードのみ返します。
この最適化が使われたかどうかは Mroonga_fast_order_limit ステータス変数を参照するとわかります。:
mysql> SHOW STATUS LIKE 'Mroonga_fast_order_limit';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| Mroonga_fast_order_limit | 1 |
+--------------------------+-------+
1 row in set (0.00 sec)
Mroonga_fast_order_limit ステータス変数はMroongaがこの最適化を使うとインクリメントされます。
この最適化は以下のすべての条件が真のときだけ使われます。
ストレージモード :
WHERE
節にある条件が1つのMATCH AGAINST
と0個以上の算術演算だけのとき。算術演算とはcolumn < 100
のような演算です。ラッパーモード :
WHERE
節にある条件がMATCH AGAINST
だけのとき。JOIN
がない。GROUP BY
がない。SQL_CALC_FOUND_ROWS
がない。LIMIT
がある。ストレージモード :
ORDER BY
節にはカラムまたはWHERE
節で使っているものと同じMATCH AGAINST
しかない。ラッパーモード :
ORDER BY
節にはプライマリキーまたはWHERE
節で使っているものと同じMATCH AGAINST
しかない。