テーブルの従業員がいるとしましょう。このテーブルで以下の2つのクエリを実行しています。
クエリ1
select * from employee where email_id = '[email protected]'
クエリ2
select * from employee where email_id = '[email protected]'
このクエリを実行している巨大なデータセットがあると仮定します。観察は、Query1はQuery2よりも非常に短い時間で済みます。また、email_id列にインデックスがないことも確認しました。私の仮定では、サーバーはQuery2ではなくQuery1をキャッシュしていると思います。それが本当なら、どうすればサーバーにQuery2をキャッシュさせることができますか?また、可能であれば、インデックスを使用せずにQuery2を最適化したいと思います。助言がありますか?
インデックスがないと、email_id
両方のクエリに同じ時間がかかり、employeesテーブルで全表スキャンを実行するのにかかる時間が予想されます。では、なぜ1つのクエリが他のクエリよりもはるかに速く返されるのでしょうか。
仮定:
select * from employee where email_id = ':1'
)。admin
電子メールアドレスの検索です。リテラルを含むクエリは通常悪いことです。各バージョンはハード解析する必要があり、カーソルキャッシュのスペースを占有します。ただし、実行パス(個別に解析されるため)やパフォーマンスプロファイルが異なる場合もあります。それがここに当てはまるようです。インデックスがない場合、アクセスパスは同じになりますが、キャッシュが原因で合計経過時間が異なる場合があります。
使用されている可能性のあるキャッシュは2つあります。
employee
レコードを含むブロック[email protected]
はすでにDBバッファキャッシュにあるため、クエリはテーブル全体を読み取る必要はありません。employee
レコード[email protected]
はそこにキャッシュされます。したがって、[email protected]
キャッシュできる理由は2つあります。明らかに、同じことがどの従業員にも当てはまります。しかし、人々は[email protected]
より頻繁に探しているようです[email protected]
。非常に簡単に言えば、(アプリケーションやデータを知らなくても)管理者ユーザーは頻繁にクエリを実行されるため、他のランダムユーザーよりもキャッシュ内にいる可能性が高くなります。
「サーバーにQuery2をキャッシュさせるにはどうすればよいですか?」
admin
ユーザーが誤ってキャッシュされた場合(クエリが頻繁に行われるため、バッファ内で保温されているだけです)、できることはほとんどありません。テーブルをメモリに固定できるのは事実ですが、それは通常は悪い考えです。ほとんどの場合、データベースは私たちよりもリソースの管理に優れています。ブロックが DB バッファ キャッシュに保持されていない場合、それはあまり頻繁に使用されていないためです (DBC のサイズが正しく設定されている場合)。
アプリケーションが結果セットキャッシュを使用している場合は、のレコードを明示的に取得できます[email protected]
。ただし、以前と同じ理由で、すべてのユーザーに対してこれを行うことはできません。レコードが頻繁に使用される場合は、レコードをメモリに固定したくないということです。
それは私たちを目標に導きます。ここで何を最適化しようとしていますか?ユーザーのサブセットのアクセス時間/または任意のユーザーのアクセス時間?後者の場合は、のインデックスが必要email_id
です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加