sql >> データベース >  >> RDS >> Mysql

whereステートメントの日付が変更されると、MySQLEXPLAINの「type」が「range」から「ref」に変更されますか?

    さまざまな検索戦略は、さまざまなデータに対して意味があります。特に、インデックススキャン(範囲など)は、実際に行を読み取るためにシークを実行する必要があることがよくあります。ある時点で、これらすべてのシークを実行すると、インデックスをまったく使用しない場合よりも遅くなります。

    簡単な例として、id(主キー)、name(インデックス付き)、birthdayの3つの列を持つテーブルを取り上げます。たくさんのデータがあるとしましょう。 MySQLにボブの誕生日を探すように依頼すると、かなり迅速にそれを行うことができます。最初に、名前インデックスでボブを見つけます(これには数回のシークが必要です。log(n)、nは行数です)。データファイルの実際の行を読み取り、そこから誕生日を読み取ります。これは非常に高速で、テーブル全体をスキャンするよりもはるかに高速です。

    次に、「Z%」のようなname like 'Z%' 。それはおそらくテーブルのかなり小さな部分です。したがって、名前インデックスのどこからZが始まるかを見つけるのはさらに速く、それぞれについてデータファイルを探して行を読み取ります。 (これは範囲スキャンです。)

    最後に、M-Zで始まるすべての名前を尋ねることを検討してください。それはおそらくデータの約半分です。範囲スキャンを実行してから、ロットを実行できます。 シークの数ですが、行の半分を読み取るという最終的な目標でデータファイルをランダムにシークすることは最適ではありません。データファイルに対して大きなシーケンシャル読み取りを行う方が高速です。したがって、この場合、インデックスは無視されます。

    これはあなたが見ているものです—あなたの場合を除いて、それが頼ることができる別の鍵があります。 (他のインデックスがない場合は、実際に日付インデックスを使用する可能性もあります。最も速いインデックスを選択する必要があります。MySQLのオプティマイザがこれでエラーを起こすことがよくあることに注意してください。)

    つまり、これは予想されることです。クエリは方法を示していません データを取得するには、と表示されます 取得するデータ。データベースのオプティマイザは、データベースを取得する最も簡単な方法を見つけることになっています。

    両方にインデックスがあります どちらの場合も、(public_key、c​​reated_on_date)の順序で列が優先され、クエリが高速化されます。これは、MySQLがテーブルごと(クエリごと)に1つのインデックスしか使用できないためです。また、範囲スキャンはインデックスの最後の列でのみ効率的に実行できるため、日付は最後になります。

    [InnoDBには実際には別の間接層があると思いますが、それは要点を混乱させるだけです。説明に違いはありません。]




    1. SQLiteAssetHelperを使用して暗号化されたDBからデータを読み取るにはどうすればよいですか?

    2. MySQLで数値の範囲を生成する

    3. SQL:使用可能なすべてのテーブルからすべてのデータを削除します

    4. mysqlに複数の行を挿入する