MariaDB はじめてのMariaDB 【第8回 SQLの高速化におけるポイント】


だいぶ、DB操作に慣れてきたと思います。
DBからデータを取得する際にSELECT文を使用しますが、
書き方によってレスポンスの速度が結構変わってきたりします。

今回は、レスポンスが早いSQLを書くポイントを記載したいと思います。

サブクエリ(服問い合わせ)の際はIN句ではなく、EXISTS句を使う

EXISTS句を使用するメリットは以下の通りです。

  • サブクエリの検索条件カラムに対し、INDEXを使用することができる。
    つまり、INDEXが設定されているカラムが検索条件に設定されている場合、
    テーブルを見るのではなく、INDEXだけで完結するということです。
  • Aテーブルに存在するデータがBテーブルに存在するかを確認するため、
    存在確認が終わった時点で、検索処理を終了します。
    IN句の場合、全件検索が行われます。

【IN句】

SELECT name FROM employee_tbl
WHERE id IN (SELECT id FROM position_tbl);

【EXISTS句】

SELECT e.name FROM employee_tbl AS e
WHERE EXISTS (SELECT * FROM position_tbl AS p WHERE e.id = p.id);

INDEXを使用する

これだけ書くと何を当たり前なことを言っているのだろう?
と思う人が多いと思いますが、INDEXを使用していると思っても
実際は使用されていない場合が多々あります。
下記は、まさにINDEXを使用していると思ってても、実際は使用されていない状態です。

  • 左辺にカラム名以外のものがある
    【算術演算子がある場合】

    SELECT name FROM employee_tbl
    WHERE salary * 1.1 >= 400000;

    【書き換えバージョン】

    SELECT name FROM employee_tbl
    WHERE salary >= 400000/1.1;

    index検証_01
    算術演算子だけではなく、SQL関数(SUBSTRE等)に関しても同様です。

ワイルドカード(*)ではなく、カラム名を書くようにする

*を使用すると、一旦カラム名に変換をかけてから実行するため、
オーバーヘッドが増加します。
また、不要カラムを表示するため、無駄にメモリを使用してしまいます。
そのため、多少手間でもカラム名をSQL文に書いた方が処理速度は向上します。
【ワイルドカード指定】

SELECT * FROM employee_tbl;

【カラム名で指定】

SELECT id, name, age, salary FROM employee_tbl;

暗黙の型変換は使用しない

MariaDBだけに関わらず、最近のDBは暗黙の型変換をしてくれるものが多いです。
【シングルクォーテーションで括る】

SELECT name, memo FROM employee_tbl WHERE memo = '500';

【暗黙の型変換を使用】

SELECT name, memo FROM employee_tbl WHERE memo = 500;

上記の例の場合、どちらを実行しても対象データを取得することはできます。
しかし、暗黙の型変換を使用した場合、1回実行した後に内部的にエラーが発生します。
その後、変換し、再実行するため、オーバーヘッドが発生します。
さらにINDEXが使用されなくなるため、検索速度も低下します。
index検証_02

複合INDEXを使用する

MariaDBもMySQLと同様に使用できるINDEXは1つのようです。
ですので、比較的頻繁に検索するSQLが分かっているのであれば
複合INDEXを使用した方が良いのではないかと思います。
index検証_03

  • このエントリーをはてなブックマークに追加

PAGE TOP