ホームページ  >  記事  >  データベース  >  mysql またはインデックスの失敗

mysql またはインデックスの失敗

PHPz
PHPzオリジナル
2023-05-18 09:18:07964ブラウズ

MySQL の IN ステートメントは、非常に一般的に使用されるクエリ ステートメントであり、一度に複数の値をクエリできます。次に例を示します。

SELECT * FROM table WHERE id IN (1,2,3, 4);

このクエリ ステートメントは、ID 1、2、3、および 4 の行を返します。 IN ステートメントの利点は、複数の OR ステートメントを使用することなく、一度に複数の値をクエリできることです。ただし、IN ステートメントに多くの値がある場合、インデックスの失敗が発生する可能性があり、クエリの効率に重大な影響を及ぼします。

インデックス障害が発生する理由とそれを回避する方法を見てみましょう。

  1. インデックス失敗の原因

IN ステートメントを使用すると、MySQL は各値を個別に比較するため、インデックスが失敗します。

注文の詳細が含まれるテーブルordersがあるとします。フィールドの1つは、注文の顧客IDを表すcustomer_idです。顧客 ID 1、2、3、4 を持つすべての注文をクエリしたいと考えています。次のクエリ ステートメントを使用できます:

SELECT * FROMorders WHERE customer_id IN (1,2,3,4);

customer_id フィールドにインデックスがある場合、MySQL はこのインデックスを参照して問い合わせてください。ただし、MySQL が IN ステートメント内の値ごとに個別の比較を行う必要がある場合、インデックス全体をスキャンする必要があり、インデックスが無効になります。

注文が 1,000 件あり、そのうち顧客 ID 1 の注文が 500 件、顧客 ID 2 の注文が 200 件、顧客 ID 3 の注文が 100 件、顧客 ID 4 の注文が 50 件あるとします。上記のクエリ ステートメントを使用する場合、MySQL はインデックス全体の 500 200 100 50 = 850 行をスキャンする必要があり、これは明らかにパフォーマンスに重大な影響を与えます。

  1. インデックスの失敗を回避する方法

インデックスの失敗を回避するために、いくつかの手法を使用してクエリ ステートメントを書き直すことができます。以下に一般的な手法をいくつか示します。

2.1 複数の OR ステートメントを使用する

IN ステートメント内の値の数が非常に少ない場合 (少数のみ)、複数の OR ステートメントを使用できます。例:

SELECT * FROMorders WHERE customer_id = 1 OR customer_id = 2 OR customer_id = 3 OR customer_id = 4;

これにより、パフォーマンスが低下することなく、MySQL がクエリにインデックスを使用するようになります。問題。ただし、IN ステートメントに多くの値がある場合、このアプローチは実現できません。

2.2 EXISTS ステートメントを使用する

もう 1 つの方法は、EXISTS ステートメントを使用して次のクエリを実行することです。

SELECT *
FROM 注文 o
WHERE EXISTS (
SELECT *
FROM (VALUES (1), (2), (3), (4)) AS c(customer_id)
WHERE c.customer_id = o.customer_id
);

このクエリ ステートメントは、IN ステートメントの値をサブクエリに配置し、EXISTS ステートメントを使用してクエリを実行します。この方法により、IN ステートメントによって引き起こされるインデックスの失敗の問題を回避できます。

2.3 一時テーブルの使用

もう 1 つの方法は、一時テーブルを使用して IN ステートメントの値を保存し、JOIN ステートメントを使用してクエリを実行することです。存在しない場合は一時テーブルを作成 tmp_customer_ids (

customer_id INT PRIMARY KEY

);

INSERT IGNORE INTO tmp_customer_ids (customer_id)

VALUES (1)、(2)、(3)、( 4);


SELECT *

FROM 注文 o

JOIN tmp_customer_ids tci ON tci.customer_id = o.customer_id;

このメソッドは、値を保存するための一時テーブルを作成します。 IN ステートメントを使用して、JOIN ステートメントを使用して、一時テーブルをクエリ用の order テーブルに接続します。この方法では、IN ステートメントによって引き起こされるインデックス障害の問題を回避でき、クエリ結果をキャッシュすることも簡単になります (MySQL は JOIN ステートメントをクエリします)。

まとめ
  1. IN ステートメントは非常に便利なクエリステートメントですが、IN ステートメントに多くの値が含まれる場合、インデックスの失敗を引き起こし、重大な影響を与える可能性があります。パフォーマンス。この問題を回避するには、複数の OR ステートメントを使用するか、EXISTS ステートメントを使用するか、一時テーブルを使用してクエリ ステートメントを書き換えます。これらの方法により、インデックスの失敗を回避し、クエリのパフォーマンスを向上させることができます。

以上がmysql またはインデックスの失敗の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。