遅延ロードmysql offsetが大きすぎるためのページングパフォーマンスの問題を解決

1691 ワード

リスト内のコンテンツを表示すると、リスト内のコンテンツの数が多い可能性がありますが、ユーザーが一度に見ることができるインタフェースの大きさは限られており、1つのインタフェースがすべてのコンテンツを表示することはできません.バックエンドから一度に多くのデータを取得すると、バックエンドに余分な圧力がかかります.
一般的に、Mysqlに格納されているデータには、idベースのページングとoffsetベースのページングの2つのページング方法があります.
次に、私が実際の生産環境で出会ったsqlを例に挙げます.関連フィールドは秘密保持の問題でA、B、Cを使用しています.代わりに.
SELECT
  *
FROM
  table_A USE INDEX (index_A)
WHERE
  A = xxx
  AND B = xxx
  AND C IN (xxx)
ORDER BY
  D DESC
LIMIT
  33380, 11

KEY `index_A` (`A`,`B`,`D`,`C`)

mysql offsetを使用してページングする場合、まず2次インデックス(index_A)に行って条件を満たすoffset+limit行レコードのidを見つけ、idデクラスタインデックスに基づいて対応する行レコードを見つけ、offset+limit行データを取り出し、最後にoffset行を捨ててlimit行だけを残すようにすると、offsetが大きい場合に効率が悪くなります.クラスタ除去インデックスに不要なデータが多すぎるためです.
上の文の実行時間は8 sくらいですが、idのページングは上と何が違いますか?idページングはバックエンドに行ってデータを要求するたびに、前のページの最後のidを持っていくことです.そうすると、mysqlに行ってデータをすくい取るときにwhere条件にid>last_を追加します.id,limit 33380,11をlimit 11に置き換え、idに従ってorder_by.これにより、クラスタインデックスに多くのデータを取得することが少なくなります.上の例では3 wを少なくして、必要な11本だけを取ることができます.
idページングの制限?idのページングには、データを取得するたびに前のページの最後のidに基づいている場合、指定したページのジャンプはできません.例えば、5ページに直接ジャンプするなど、データをロードするときにより多くのボタンを使用します.
上記のsqlのサービスがidページングに変更されると、製品ページング設計を変更する必要があり、フロントエンドも調整する可能性があり、変更は大きくなります.offsetが大きすぎることによるページングパフォーマンスの問題を解決するために、遅延ロードの方法があります.
上記の例のsqlを2つに分解します.
1.
SELECT
  table_A.id
FROM
  table_A USE INDEX (index_A)
WHERE
  A = xxx
  AND B = xxx
  AND C IN (xxx)
ORDER BY
  D DESC
LIMIT
  33380, 11;

2.
Select * from table_A where id in (ids)

2つのクエリの合計時間は約50 msで、前の8 sよりずっと速くなりました.理由は次のとおりです.
最初のクエリは、すべてのクエリのカラムが2次インデックス(index_A)にあるため、クラスタインデックスのデータ行にアクセスする必要がなく、効率が速く、必要な11のレコードのidを取得することができ、その後、2番目のsqlがidに基づいてクラスタインデックスにデータを取得するのも速いため、インデックスを上書きします.