だいぶ、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;
ワイルドカード(*)ではなく、カラム名を書くようにする
*を使用すると、一旦カラム名に変換をかけてから実行するため、
オーバーヘッドが増加します。
また、不要カラムを表示するため、無駄にメモリを使用してしまいます。
そのため、多少手間でもカラム名を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を使用する
MariaDBもMySQLと同様に使用できるINDEXは1つのようです。
ですので、比較的頻繁に検索するSQLが分かっているのであれば
複合INDEXを使用した方が良いのではないかと思います。
WEBアプリケーション関連 人気連載リンク
データベースの基礎が学べるSQL基礎講座
SQL基礎 連載
より実践的なWEBアプリ開発講座!Bootstrap活用を学ぶなら・・
魁!小野の塾 連載