Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

データベースに関する処理の中で、SQLでパフォーマンスを上げるためにヒント句を記述するという方法を聞いたことがある方も多いと思います。

今回は、SQLのヒント句とはどういったものなのかといった基本情報から、MySQLで利用するヒント句の使い方についてご紹介していきたいと思います。

ポテパンダの一言メモ

ヒント句の記述方法はデータベース毎に異なります。
ご利用のデータベースに合わせて適宜読み替えをお願いします。

SQLのヒント句って何?


SQLのヒント句は、データベースが実行計画を作成する際、意図しない実行計画が作成されないよう、ユーザーがオプティマイザを導くために利用されるものです。

オプティマイザはデータベース毎に搭載されており、ある程度的確な実行計画をユーザーが指定しなくても作成してくれます。

しかし、オプティマイザが常にユーザーの意図した実行計画を作成出来るとは限らないため、ヒント句を用いることで実行計画の作成を補助することが可能となります。

MySQLでのヒント句利用方法とは?!


SQLのオプティマイザといえば、Oracleデータベースがサンプルとして挙げられることが多いようですが、MySQLでもヒント句を使ってオプティマイザの実行計画作成を補助することが可能です。

上述したように、オプティマイザはデータベース毎に異なるシステムが搭載されているため、記述方法は各データベースにより異なります。

MySQLでのヒント句の記述方法

MySQLではヒント句を「インデックスヒント」とも呼びますが、主な記述方法として「USE」「IGNORE」「FORCE」の3種類が存在します。

USE

USEは名前の通り、指定したインデックスを使用するようにオプティマイザに推奨する方法です。

ただし、オプティマイザがインデックスを使用するよりもフルスキャンした方が早いと判断した場合には、USEで指定したインデックスを使用せず、フルスキャンによる処理が実行される可能性もあります。

FORCE

FORCEは上述したUSEと同じく、指定したインデックスを使用するようにオプティマイザに推奨する方法ですが、より強制力の強い指定方法となります。

オプティマイザがインデックスを使用するよりもフルスキャンの方が早いと判断した場合でも、FORCEを指定した場合にはインデックスを利用した処理が実行されます。

つまり場合によっては、インデックスヒントを指定しない場合よりも処理が遅くなってしまう可能性があるということです。

IGNORE

IGNOREでは、指定したインデックスをオプティマイザに使用しないよう推奨する方法です。

明らかに処理が遅くなるインデックスを指定しておくことで、オプティマイザが採用する可能性を除外することが可能となります。

SQL構文

SQLでインデックスヒントを利用するにはFROM句の後に記述します。

SELECT カラム名[, カラム名, ...]
FROM テーブル名
USE[or INGORE or FORCE] [FOR JOIN or ORDER BY or GROUP BY] (インデックス名)
[WHERE 条件式];

FORを指定しなかった場合には、JOIN・ORDER BY・GROUP BY全てに対してインデックスが適用されます。

SQLのヒント句を実際に使ってみよう


ではSQLのヒント句を実際に使ってみましょう。

今回は下記コマンドでサンプル用のテーブルを用意しました。

CREATE TABLE test1
(
    id INTEGER PRIMARY KEY 
    ,name VARCHAR(30)
    ,price BIGINT
    ,category VARCHAR(20)
);

インデックスは下記のコマンドで設定しています。

CREATE INDEX index_name ON test1 (name);
CREATE INDEX index_category ON test1 (category);
CREATE INDEX index_price ON test1 (name, price);

サンプルとしてデータを下記のように登録しました。

INSERT INTO test1
VALUES 
(1,'商品1',10000,'カテゴリー1')
,(2,'商品2',30000,'カテゴリー1')
,(3,'商品3',20000,'カテゴリー2')
,(4,'商品4',60000,'カテゴリー2')
,(5,'商品5',50000,'カテゴリー3')
,(6,'商品6',4000,'カテゴリー3')
,(7,'商品7',5000,'カテゴリー3')
,(8,'商品8',6000,'カテゴリー3');
ポテパンダの一言メモ

サンプルテーブルとデータはヒント句の動きを確認するためだけのもので、簡易的に作成しています。

実行計画を確認してみよう

実行計画を確認するには「EXPLAIN句」を利用します。

EXPLAIN
SELECT * FROM test1
WHERE name = '商品4' AND price > 50000;

実行した結果が下記の通りです。

+----+-------------+-------+------------+------+------------------------+------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys          | key        | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+------------------------+------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | test1 | NULL       | ref  | index_name,index_price | index_name | 123     | const |    1 |    33.33 | Using where |
+----+-------------+-------+------------+------+------------------------+------------+---------+-------+------+----------+-------------+

ヒント句で指定しない場合、実行計画では利用可能なインデックスに「index_name」「index_price」が表示され、実際に利用されたのは「index_name」だったことが確認出来ます。

USE INDEX

EXPLAIN
SELECT * FROM test1
USE INDEX (index_price)
WHERE name = '商品4' AND price > 50000;

実行した結果が下記の通りです。

+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key         | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | test1 | NULL       | range | index_price   | index_price | 132     | NULL |    1 |   100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+

USE INDEXで「index_price」を指定していますので、利用可能なインデックス・利用されたインデックス共に「index_price」が表示されています。

FORCE INDEX

EXPLAIN
SELECT * FROM test1
FORCE INDEX (index_name)
WHERE name = '商品4' AND price > 50000;

実行した結果が下記の通りです。

+----+-------------+-------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key        | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | test1 | NULL       | ref  | index_name    | index_name | 123     | const |    1 |    33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------------+---------+-------+------+----------+-------------+

今回はFORCE INDEXで「index_name」を指定していますので、利用可能なインデックス・利用されたインデックス共に「index_name」が表示されています。

IGNORE INDEX

EXPLAIN
SELECT * FROM test1
IGNORE INDEX (index_name)
WHERE name = '商品4' AND price > 50000;

実行した結果が下記の通りです。

+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key         | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | test1 | NULL       | range | index_price   | index_price | 132     | NULL |    1 |   100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+

IGNORE INDEXで「index_name」を指定していますので、オプティマイザが「index_name」以外で利用可能と判断した「index_price」を表示していることが確認出来ます。

さいごに:SQLのヒント句を活用してパフォーマンスを向上させよう!


本記事では、SQLのヒント句の使い方について、MySQLをサンプルとしてご紹介してきました。

今回のサンプルは少量のデータしか投入していないため、インデックスを変更したところで処理速度はほとんど変わりません。

しかし大容量のデータベース処理となるほど、適切なインデックスが利用されているかにより大きく処理速度が変わりますので、日頃から実行計画を確認し、意図したインデックスが利用されているか確認しておく癖を付けておくことは大切です。

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。