メインコンテンツにスキップ
モジュール 10 · レッスン 3 / 4コース内の 39/57~12 min
モジュールのレッスン (3/4)

複合インデックスと部分インデックス

前のレッスンでは、線形 DBMS クエリ (WHERE country = 'Italy') のインデックスの使用について説明しました。 2 つの組み合わせた前線で検索するとどうなるでしょうか?

たとえば、実際の電子商取引では、特定の顧客 ID に属し、かつ 指定された時間範囲内にある注文を検索したい場合があります。 WHERE customer_id = 90 AND placed_at >= '2025-01-01'。

customer_id にベース インデックスしかない場合、Postgres はバイナリ ツリーを使用して顧客の 50 件の注文をすぐに見つけますが、その後、50 件すべてを手動で順番に反復処理し、日付を目視で遅延フィルタリングする必要があります。

複合インデックス

DBMS に対して、単一のキー ディメンションに沿ってではなく、複数のキー ディメンションに沿って「分析辞書」ファイルを順序付けるように指示できます。

SQL
CREATE INDEX idx_orders_customer_date ON orders(customer_id, placed_at);

「複合」インデックスは、パラメータの順序を非常に重要なものとして扱います。ここでは、B ツリー ノードが customer_id をブロック (分離のために最も区別できるブロック) にグループ化し、厳密に分類します。それらの内部には、完全にソートされた順序でさまざまな placed_at 時間値で分岐するサブツリーが存在します。

この構造は、複数のネストされた述語を持つ WHERE 句を残酷に消滅させます。

部分インデックス (フィルターされたインデックス)

すべてのインデックスにはディスク容量とユーザー入力ストリームの CPU がかかります。 電子商取引で常にフィルタを並べ替えたり取得したりする必要があるが、それが少数のレコードに対してのみである場合はどうなるでしょうか? (例: 未読通知チェックを迅速にポーリングする。) 「未読」がそのうちの 5 件のみを表す場合、10,000,000 件の通知すべてに対して「is_read」インデックスを作成するのは非常に面倒です。

SQL
CREATE INDEX idx_unread_notifs ON notifications(user_id)
  WHERE is_read = false; -- Questa aggiuntiva è l'"Indice Parziale"

データベースは、レコードが未読の場合にのみ DB へのクイック アクセス キーを保存する超高速の B ツリーを構築します。ディスクは、1,000 万のインデックスではなく、5 行 (3 バイト) のインデックスに夢中になります。高速 SELECT の利点は次のとおりです。

SELECT * FROM notifications WHERE user_id = 2 AND is_read = false;

あなたの番です

運動#sql.m10.l3.e1
試行回数: 0読み込み中…

一時パスワード/リセットトークンの検索を最適化したいと考えています。特定の国と既知の都市を組み合わせて登録したすべての顧客を検索する SELECT 呼び出しを頻繁に実行します。\n「customers」に「idx_cust_loc」という名前の複合インデックスを作成します。最初に「country」フィールド (より排他的) を渡し、次に「city」フィールドを渡します。

エディターを読み込み中…
ヒントを表示

構文: CREATE INDEX name ON table(col1,col2);

3 回の試行後に解決策が利用可能になります

条件付き (部分) インデックスの探索

運動#sql.m10.l3.e2
試行回数: 0読み込み中…

ショッピング ユーザーの検索を最適化します。ユーザーは事前登録しますが、登録する必要があるのは時系列のサインアップ順にリストするだけです (「顧客」の「signed_up_on」にインデックスを作成します)。ただし、完全な文字列「都市」: 「ミラノ」の顧客のみに限定されます。

エディターを読み込み中…
ヒントを表示

これは通常、ターゲット プロパティで宣言されます。最後にマジック キーワード WHERE city = 'Milano' を追加します。

3 回の試行後に解決策が利用可能になります