メニューを閉じる

テクノデジタルグループ

メニューを開く

2024.01.25

DB

【弊社紹介】社内勉強会開催!〜SQL高速化のために〜

目次

  • はじめに
  • 今回の勉強会
  • ・今回の勉強会テーマ
  • ・インデックスについて
  • ・インデックス性能検証クイズ
  • 終わりに

はじめに

 本稿をご覧いただいております皆様こんにちは。MTです。
先月になりますが、弊社内の開発ユニットが持ち回りで実施している勉強会が再び開催されたので、今回もそのご紹介をしたいと思います。
今回はクイズもあるので、目を通していただけると嬉しいです。

今回の勉強会

今回の勉強会テーマ

 今回の勉強会のテーマは、インデックスを主としたSQL高速化です。
インデックスは、予めソートした索引列を作成しておくことで、検索の高速化を行います。

 インデックスはとても便利なものですが、扱い方によってはむしろパフォーマンスを落とす事になります。
今回の勉強会では、この扱いを間違わないために、様々なケースをテストした結果を比較検討したものをクイズとして発表していました。
本稿では、その勉強会の内容として、インデックスのもう少し詳しい紹介と、そのクイズを掲載します。

インデックスについて

■ インデックスとは

 インデックスは前述の通り、あらかじめソートした索引列によって検索を高速化するものです。
インデックスが無い場合だと、WHERE句で絞り込みをするとデータベース内の全レコードを探索して、その結果を表示します。データ数が少なければ問題ないかもしれませんが、業務で使うような莫大なデータをそれで検索すると、途方もない時間がかかりそうですね、、、

 インデックスの例を示します。例えば下の画像のように人名のデータカラムがあれば、そのカラムの内容をアルファベット順に並べた索引が作成されます。これがインデックスです。

■ インデックスがあるとなぜ検索が速くなるのか

 なぜこれで検索が早くなるのか、というとインデックスが保存されるデータ構造に理由があります。

インデックスは主にツリー構造と呼ばれるデータ構造によってデータが保存されます。例えば以下のような構造です。
(※今回の勉強会で扱ったMySQLのB+Tree構造の他にB-Tree構造を採用したデータベースも存在しますがここでは詳細説明を割愛します。主な構造の違いはB+Tree構造はデータが葉ノードにのみ存在し、葉ノード同士をつなぐポインタが存在する点です)

 ご覧いただいております通り、アルファベット順に並んだ葉ノードを含む親ノードが、ある程度のサイズで区切られ、親ノードから一番近い子ノードを辿ることでデータに検索数を少なくしてアクセスができるようになっています。

■ インデックスの注意点

このように、検索を効率化することのできるインデックスですが以下の欠点があります。

読み込み速度が速くなる代わりに、書き込み速度が遅くなる

 INSERT文の実行時に、テーブル内の全インデックスにデータを追加して探索用のツリー構造を最適化処理が走るためです。
したがって、インデックスを作成する際には、必要最小限にとどめる必要があります。

 では、どのようなカラムがインデックスに向いているのでしょうか。
インデックスの目的から考えていきます。インデックスの目的、検索の効率化でしたね。
検索が効率化されるということは、インデックスによって絞り込める情報が広がる必要があります。

例えば、氏名、生年月日、性別を記載した名簿があったとして、どちらが個人の検索に有効でしょうか。

1:氏名に張る 2:性別に張る

 性別での検索は、一般的な選択肢だと多くても3値ほどしか絞れず、検索結果として十分に絞り込めていない状態になります。
 一方氏名での検索は、同姓同名の人がいる可能性があるので、必ず一つとは言わないが、ほぼ絞り込めますよね。したがって、「1:氏名に張る」の方が検索に有効だと考えられます。

 このように、インデックスの選択性が高まるカラム、つまりデータの種類が多い(情報量の多い)カラムに対してインデックスを張るのが効果的です。
 ちなみに、テーブル内で一意であることが約束されている「PRIMARY KEY制約」「UNIQUE制約」は選択性の高い値ですが、自動的にインデックスが作成されるため、改めて自分で作成する必要はありません。

 また、インデックスによってどれほど効率化ができているか、そもそもインデックスが使えるのか、ということを確認しながら調整したい時は、EXPLAIN句で実行計画を表示するのが便利です。

インデックス性能検証クイズ

 お待たせいたしました。ここからは勉強会で紹介された、性能比較クイズに関して実際のスライドをお借りしてご紹介します。
 こちらではインデックスに加え、試験的に指定方法の違いを試すなどした結果をクイズにしています。
その数なんと11問。ぜひ実際に解いてみてください。
(ちなみに、弊社の勉強会はオフライン開催とGoogle Meetを併用しているのですが、このクイズの解答には、Meetのアンケート機能を利用していました。便利で面白かったので、機会があれば真似したいです)

第1問

COUNT句で件数を取得するときはインデックスは利用されるでしょうか?

第2問

LIKE句でワイルドカードを適用するとき、前方一致と部分一致でどちらが早いでしょうか?

第3問

算術演算子を用いたWHERE句はインデックスの対象になるでしょうか?

第4問

IN句の記述を行うときデータの割合が多い物を、左(先)に置く場合と右(後)に置く場合、どちらが早いでしょうか?

第5問

アスタリスクと全カラム指定はどちらが早いでしょうか?

第6問

BETWEENと比較演算子ではどちらが早いでしょうか?

第7問

型指定した時に、BETWEENと比較演算子ではどちらが早いでしょうか?

第8問

大文字の予約語と小文字の予約語、どちらが早いでしょうか?

第9問

IN句とEXIST句ではどちらが早いでしょうか?

第10問

DISTINCT句とEXIST句では、どちらが早いでしょうか?

第11問

複合インデックスを設定しているときに、インデックスの指定順とWEHERE条件の指定順は関係があるでしょうか?

おわりに

 以上で、今回実施された勉強会についてのご紹介を終わらせていただきます。
 SQLのパフォーマンスチューニングは、規模の大きかったり、コストを限界まで抑えたりする際には、避けて通れないものです。インデックスを活用して、性能を最大限引き出せるよう頑張りたいですね。
 閲覧いただきありがとうございました。感想フォームなども下にありますのでよければご意見をお聞かせください。
次回の記事もご覧いただけますと幸いです。MTでした。

【記事への感想募集中!】

記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!
  • こんな記事が読んでみたい、こんなことが知りたい、調べてほしい!という意見も募集中!
  • いただいた感想は今後の記事に活かしたいと思います!

感想フォームはこちら


【テクノデジタルではエンジニア/デザイナーを積極採用中です!】

下記項目に1つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』

【テクノデジタルのインフラサービス】

当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。

https://www.tcdigital.jp/infrastructure/

最近の記事