Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MySQL のインデックスの種類をおさらいしよう! / overviewing indexes in MySQL

MySQL のインデックスの種類をおさらいしよう! / overviewing indexes in MySQL

2024/03/07~09 開催の「PHPerKaigi 2024」(https://phperkaigi.jp/2024/ )の LT 資料です。

詳細:https://fortee.jp/phperkaigi-2024/proposal/a28d42c5-9df5-4c17-bc11-90643425fe25

Shohei Okada

March 09, 2024
Tweet

More Decks by Shohei Okada

Other Decks in Programming

Transcript

  1. よくみるインデックス CREATE TABLE `users` ( `id` VARCHAR(20) NOT NULL PRIMARY

    KEY, `created_at` BIGINT UNSIGNED NOT NULL, INDEX `users_created_at` (`created_at`) ); CREATE INDEX `users_created_at` ON `users` (`created_at`); あるいは
  2. • 全文検索用のインデックス • 自然言語検索とブール検索の 2 つのモード • 転置インデックスという形でデータを持つ • 日本語ではパーサーの指定が必要

    • 単語間がスペースで区切られていないため • そこまで MySQL にやらせるか、は要検討か FULLTEXT https://dev.mysql.com/doc/refman/8.0/ja/fulltext-search.html
  3. FULLTEXT 通常のインデックスが効かない検索を高速に行える SELECT * FROM `posts` WHERE MATCH (`title`) AGAINST('PHP'

    IN NATURAL LANGUAGE MODE); SELECT * FROM `posts` WHERE MATCH (`title`) AGAINST('+PHP -MySQL' IN BOOLEAN MODE);
  4. • 空間データ型向けのインデックス • POINT 型, GEOMETRY 型など • R 木というデータ構造

    • ISUCON10 予選の解説にも登場 SPATIAL https://dev.mysql.com/doc/refman/8.0/ja/spatial-index-optimization.html
  5. • 複数のカラムに対するインデックス • AND 検索や ORDER BY での複数指定に対応 • 定義する際のカラムの順番に意味がある

    • 定義と一致する順番にしか効かない • 本の索引で 2 文字目から探せないのと同じ 複合インデックス https://dev.mysql.com/doc/refman/8.0/ja/multiple-column-indexes.html
  6. 複合インデックス CREATE INDEX `users_idx1` ON `users` (`created_at`, `updated_at`); SELECT *

    FROM `users` ORDER BY `created_at`, `updated_at`; SELECT * FROM `users` ORDER BY `created_at`; SELECT * FROM `users` ORDER BY `updated_at`, `created_at`; ⭕ ⭕ ❌
  7. SELECT * FROM `users` ORDER BY `created_at` ASC, `updated_at` DESC;

    降順インデックス CREATE INDEX `users_idx1` ON `users` (`created_at` ASC, `updated_at` ASC); CREATE INDEX `users_idx2` ON `users` (`created_at` ASC, `updated_at` DESC); ⭕ ❌
  8. 1 レコードに対して複数のインデックスレコード (例)JSON 型内の配列 複数値インデックス https://dev.mysql.com/doc/refman/8.0/ja/create-index.html#create-index-multi-valued CREATE TABLE `users` (

    `id` VARCHAR(20) NOT NULL PRIMARY KEY, `profile` JSON, INDEX ((CAST(`profile`->'$.zipcode' AS UNSIGNED ARRAY))) ); SELECT * FROM `users` WHERE 94507 MEMBER OF(`profile`->'$.zipcode');
  9. • 演算結果の値に対するインデックスを作成できる • MySQL 8.0.13~ • 公式リファレンスの翻訳が不安定 • 「機能キー部品」「関数キー部分」 関数キーパーツ(functional

    key parts) https://dev.mysql.com/doc/refman/8.0/ja/create-index.html#create-index-functional-key-parts CREATE INDEX `idx1` ON `t1` ((`col1` + `col2`));