ページングクエリ最適化ソリューションの概要
関数やスキャンレコードなどが多すぎるとクエリの速度に影響します。SQLステートメントのクエリ速度を向上させる方法は非常に重要です。 SQLクエリの最適化方法をいくつか示します。
1.一般的に使用されるページングクエリ
(1)未使用のインデックス
データ量が少ないテーブルの場合(select * from table limit x,y)
、フォームを使用してページングクエリを完了することがよくあります。例えば:
select * from areas limit 0,20; (第一页)
select * from areas limit 20,20;(第二页)
select * from areas limit 40,20;(第三页)
この方法でのクエリはインデックスを使用しないため、完全なテーブルクエリが実行されます。データ量が多いと速度が非常に遅くなります。
(2)インデックスを使用する
インデックスを使用すると、スキャンされるレコードの数が大幅に減少します。クエリを表示するには、以下の説明を使用してください。
explain select * from areas order by id desc limit 300,20;
ここorder by id
での使用目的は、idの主キーインデックスを使用することです。そうしないと、クエリは完全なテーブル検索になります。ここでクエリされる行は、クエリ時にスキャンされたレコードの数を表します。制限の開始点が300の場合、レコード数は320です。開始点が1000000の場合、クエリレコードの数は100020です。これは、開始点がさらに進んでいる後で、クエリ速度が遅くなり、開始点が終了に達すると、完全なテーブル検索と同等になり、この時点でインデックスの意味が失われます。
この種のインデックスクエリメソッドはよく使用されますが、この種のクエリをテーブルに返す必要があります。つまり、2番目のクエリが必要です。テーブル操作に戻らないようにするために、クエリを最大限に実行するには、遅延関連付けの使用をお勧めします。カバーリングインデックスを使用します。
(3)説明のフィールド解釈:
1)id:識別子
2)select_type:クエリのタイプ:
- SIMPLE:単純なSELECTステートメント(UNION操作またはサブクエリ操作を含まない)
- PRIMARY:クエリの最も外側のSELECT(たとえば、2つのテーブルがUNIONを実行するか、サブクエリがあり、外側のテーブル操作がPRIMARYで、内側の操作がUNION)
- サブクエリ:サブクエリの最初のSELECT(複数のサブクエリが存在する場合)
- 派生:ドリブンSELECTサブクエリ(サブクエリはFROM句にあります)
3)テーブル:結果テーブル
4)パーティション:一致するパーティション
5)タイプ:テーブルの接続タイプ、
- クエリのパフォーマンス:system> const> eq_ref> ref> range> index> all
- ALL:全表スキャン。MySQLはテーブル全体をトラバースして一致する行を見つけます
- index:フルインデックススキャン。indexとALLの違いは、インデックスタイプがインデックスツリーのみをトラバースすることです。allとIndexの両方がテーブル全体を読み取りますが、indexはインデックスから読み取られ、allはハードディスクから読み取られます。
- range:指定された範囲の行のみを取得し、インデックスを使用して行を選択します
- ref:上記のテーブルの接続一致条件、つまり、インデックス列の値を見つけるために使用される列または定数を示します
6)possible_keys:インデックスを使用できます
7)キー:実際に使用されるインデックス
8)key_len:インデックスフィールドの長さ
9)ref:列とインデックスの比較
10)行:スキャンされた行の数
11)フィルター処理:テーブル条件によってフィルター処理された行のパーセンテージ
12)追加:実装の説明と説明
- 一時テーブルの使用:一時テーブルは中間結果を保存するために使用されます。MySQLはクエリ結果をソートするときに一時テーブルを使用します。一般的に、並べ替え順およびクエリグループ化で使用されます。
- インデックスの使用:テーブルのデータ行へのアクセスを回避するために、対応する選択操作でカバーインデックスが使用され、効率が良好であることを示します。
- whereの使用:フィルタリングが使用される場所を示します
詳細に説明する:https://blog.csdn.net/why15732625998/article/details/80388236
2、ページングクエリの最適化
1最大IDクエリメソッド
select * from areas where id>2000 limit 20;
このテストデータには、合計3750個のデータ(id> 2000)があります。つまり、照会されたレコードの数は、id = 2000以降のデータです。
注:
最大IDクエリメソッドは、自己インクリメントコンポーネントにのみ適用できます。uuidによって生成された主キーは、このメソッドには適していません。
との間の2
select * from user where id between 2000 and 2010;
このようにも 自己インクリメントする主キーにのみ適用でき、IDは壊れていません、それ以外の場合、この方法はお勧めしません。BETWEENANDを使用すると、11個のレコードを照会できます。ここで、BETWEENANDには両側の境界条件が含まれていることに注意する必要があります。
3制限ID
select * from areas where id>(select id from areas limit 2000,1)
limit 20;
この方法で3750行のレコードがスキャンされますが、idが主キーであるため、主キーインデックスがあります。、したがって、主キーIDの制限範囲クエリはselect * from areas limit 2000,20;
それよりもはるかに高速です。
SUBQUERY:サブクエリはSELECTまたはWHEREリストに含まれています
4遅延アソシエーション
カバーするインデックス:InnoDBのセカンダリインデックスは、行のプライマリキー値をリーフノードに格納するため、セカンダリプライマリキーはクエリをカバーでき、プライマリキーインデックスのセカンダリクエリを回避できます。必要なデータ列は、インデックスから取得するだけでよく、テーブルに戻る必要はありません。つまり、データ行を見つけるために主キーインデックス領域に移動する必要はありません。
アソシエーションの遅延 :SQLステートメントのクエリ機能を可能な限り向上させるために、SQLステートメントの一部でカバーインデックスを使用してクエリを実行します。
エイドフィールドに共通のインデックスキー入力を作成しました。
select * from areas a join (select aid from areas
limit 2000,20) b on a.aid = b.aid;
クエリの最初の段階では、カバーリングインデックスを使用してselect aid from areas limit 2000,20
、from句のサブクエリでマッチングエイドを見つけました。次に、これらのエイドに従って、すべての列値が外部クエリマッチングで取得されます。インデックスを使用してクエリ全体をカバーすることはできませんが、インデックスカバレッジをまったく使用できないよりはましです。
注意:
- 4の制限IDもカバーするインデックスを使用しますが、クエリには遅延アソシエーション結合を使用することをお勧めします。サブクエリは使用しないでください。より多くのフィールドがあり、タイプの長さが長い場合、遅延関連付けもより有利です。
- 選択操作でカバーインデックスを使用すると、Explainのextreに使用インデックスが表示されます。
- id値が大きいほど、クエリの優先度が高くなります。
- FROMリストに含まれるサブクエリは
devived2
、派生した領域のテーブルを参照するDERIVED(派生)としてマークされます。
5ポイントテーブルクエリ
MySQLでは、テーブルのストレージが500wを超えないようにすることをお勧めします。クエリ400wは、一般的なクエリでは1秒未満です。より高速な場合は、2つの状況に分けることができる個別のテーブルストレージを使用することをお勧めします。サブテーブルは垂直サブテーブルにあります。
(1)水平サブテーブルテーブル
の元のデータに900wのデータがある場合、3つのテーブルに保存でき、各テーブルには300万のデータが保存されるため、クエリを実行する際のプレッシャーが大幅に軽減されます。、そして効率が非常に高いので、問題はこのレベルの水道メーターをどのように実現するかです。たとえば、mycat
このようなミドルウェアを使用できます。AlibabaCloudはデータベースシャーディングテクノロジーも提供します。もちろん、自分でテーブルを手書きすることもできますが、自分でテーブルを手書きする場合は、注意が必要です。 IDの複製と、そのテーブルで現在のIDを定義する方法。アルゴリズムでは、ハッシュ値を使用することをお勧めします。
(2)垂直サブテーブル
レコードに100wがある場合、クエリ速度は通常は遅くなりすぎないはずですが、このテーブルにはフィールドが多すぎ、テキストタイプのフィールドが多いため、このとき、1つのテーブルで占有するスペースが少ないフィールドと、別のテーブルで占有するスペースが多いフィールドを分割できます。、2つのテーブルが1つずつ関連付けられているため、クエリがはるかに高速になります。
(3)コールドテーブルとホットテーブル。
コールドテーブルとホットテーブルもサブテーブルのアイデアです。たとえば、銀行が請求書をクエリすると、最近の月のデータしかクエリできないことがわかります。前のデータは、過去の請求書を照会するためのカウンター。銀行照会データが使用されます。ホットテーブルとコールドテーブルの設計アイデア。
2つの同一のテーブルを作成します。1つのテーブルには過去3か月のレコードが格納されます:テーブルa、もう1つのテーブルには3か月前のデータが格納されます:テーブルb。ユーザーによって生成された新しいレコードはテーブルaに格納できます。毎朝定期的にテーブルをスキャンできます。レコードが3か月前であれば、レコードをテーブルbに移行できます。ユーザーにとっては、過去3か月間のデータをクエリするときの感度が高く、3か月前のデータをあまりクエリしない可能性があるため、この設計は完全に合理的です。
6インデックス
インデックスを追加すると、クエリの効率が向上します。ページングクエリに条件が含まれる場合は、条件にインデックスを追加できます。データベースは、対応するインデックステーブルを維持します。クエリを実行すると、最初にインデックステーブルがクエリされ、に基づいてレコードが直接クエリされます。インデックステーブルから返されるレコード。テーブルでは、スキャンされる行数も減少しますが、次の点が発生する限り、インデックスがトリガーされない可能性があることに注意する必要がありますので、注意してください。
- クエリ条件がnullではありません
- '%notebook'のようなキーワードなどのステートメントのように、インデックスは無効であり、%を先頭に置くことはできません。
- ORの前後の条件のいずれかがインデックスを追加しない限り、テーブル全体がスキャンされ、インデックスは無効になります。
- 複合インデックス:複合インデックスを使用する場合は、最初のインデックスフィールドを指定する必要があります。そうしないと、複合インデックスが有効になりません。
> 、< 、 <>。
- 一重引用符のない文字列
7キャッシュ
クエリ結果をredisにキャッシュすると、ハードディスクデータをクエリせずにメモリが直接読み取られます。
注:
クエリ最適化の焦点は、最小数のレコードをスキャンし、クエリの結果を返し、キャッシュを使用してデータベースアクセスを減らす方法にありますが、これは症状を解決し、根本的な原因ではありません。美しいsqlを記述することによってのみ可能です。プログラムは無敵です。
参照ブログ:https://blog.csdn.net/qq_33220089/article/details/105012663