百万データベースの量の下でデータを、そのページングクエリ最適化の方法を持っています

データベースクエリのテーブルからのレコードの数万人の必要性は、すべて1回のクエリの結果は非常に遅くなります場合は、データの増加量は特に明らかで、特にして、あなたは、ページングクエリを使用する必要があります。データベースクエリのページでは、多くの方法および最適化のポイントがあります。

私の知っている方法のいくつかについて、以下簡単に。

準備

試験のために下記の数を最適化するために、テーブルを有し、以下に説明します。

  • 表名:order_history

  • 説明:事業の受注履歴テーブル

  • メインフィールド:unsigned int型ID、TINYINT(4)int型

  • フィールド:表の37項目の合計、および他の大きなテキストデータが含まれていないが、VARCHAR(500)まで、IDフィールドはインデックスであり、そしてインクリメントされます。

  • データ容量:5709294

  • MySQLのバージョン:5.7.16テストテーブルの百万ラインを見ては、あなたが自分自身をテストする必要がある場合は、挿入されるデータをテストするためにシェルスクリプトを書くことができ、容易ではありません。すべての次のSQL文の実行環境は変化しなかった、次は、基本的なテストの結果、次のとおりです。
    select count(*) from orders_history;

戻る:5709294

3件の問い合わせ時間は以下の通りでした。

  • 8903ミリ秒

  • 8323ミリ秒

  • 8401ミリ秒

一般的なページングクエリ

シンプルな制限句を使用して、一般的なページングクエリを達成することができます。文の次の句を制限します:

SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset

LIMIT句はSELECTステートメントによって返されるレコードの数を指定するために使用することができます。次の点に注意してください。

  • 最初の引数は最初から返します注意のオフセットの行を指定し  0、スタート

  • 2番目のパラメータは、返される行の最大数を指定します

  • 引数を1つしか与えられている場合:これは、返される行の最大数を表し

  • -1の2番目のパラメータは、すべての行の末尾にレコードのセットからオフセット取得します

  • 0は最初の行(の代わりに、1)であるオフセット

以下では、アプリケーションの例です。

select * from orders_history where type=8 limit 1000,10;

記事では、テーブルORDERS_HISTORYから声明照会しますoffset:1000条に、つまり、データの開始後、1010のデータを条1001 10( 1001<=id<=1010)。

上記のデフォルトに対応するマスターキー(通常はID)ソート結果を使用して、データテーブルのレコード:

select * from orders_history where type=8 order by id limit 10000,10;

3件の問い合わせ時間は以下の通りでした。

  • 3040ミリ秒

  • 3063ミリ秒

  • 3018ミリ秒

このクエリに応答して、時間の次のテストのクエリインパクトレコード量:

select * from orders_history where type=8 limit 10000,1;
select * from orders_history where type=8 limit 10000,10;
select * from orders_history where type=8 limit 10000,100;
select * from orders_history where type=8 limit 10000,1000;
select * from orders_history where type=8 limit 10000,10000;

次の3つのクエリの時間は以下のとおりです。

  • 3072ms 3092ms 3002ms:レコードを照会します

  • クエリ10レコード:3081ms 3077ms 3032ms

  • クエリ100のレコード:3118ms 3200ms 3128ms

  • クエリ1000年の記録:3412ms 3468ms 3394ms

  • クエリ10000のレコード:3749ms 3802ms 3696ms

私はまた、より多くのは、それがあまりにもかかる時間の問い合わせ記録量として12回のクエリ、ビューの点から、クエリ時間は、100未満のクエリレコード量の時点で、ほぼ確実に、基本的に差はないクエリ時間を、やりましたより多くの。

お問い合わせは、テストをオフセット:

select * from orders_history where type=8 limit 100,100;
select * from orders_history where type=8 limit 1000,100;
select * from orders_history where type=8 limit 10000,100;
select * from orders_history where type=8 limit 100000,100;
select * from orders_history where type=8 limit 1000000,100;

次の3つのクエリの時間は以下のとおりです。

  • クエリ100は、オフセット:25msのの24msの24ms

  • クエリ1000は、オフセット:78msの76msの77ms

  • クエリ10000オフセット:3092ms 3212ms 3128ms

  • 3878msの3812msの3798ms:100 000オフセットを照会します

  • クエリー1万人がオフセット:14608ms 14062ms 14700ms

クエリの増加で相殺された後、特にクエリがオフセット100,000を超える、クエリ時間の急激な増加です。

このページングクエリはデータベースから最初のレコードのスキャンを開始しますので、より多くの後方に、より遅いクエリの速度が、より多くのデータのクエリは、クエリが全体の速度が遅くなります。

サブクエリの最適化の使用

このように第一位置決めIDは、後で問い合わせをオフセット位置、及び、この方法は、ID増分の場合にも適用可能です。

select * from orders_history where type=8 limit 100000,1;

select id from orders_history where type=8 limit 100000,1;

select * from orders_history where type=8  and
id>=(select id from orders_history where type=8 limit 100000,1)
limit 100;

select * from orders_history where type=8 limit 100000,100;

次のようにクエリ時間4文は次のとおりです。

  • 文の第1条:3674ms

  • 第2条声明:1315ms

  • 声明の第3条:1327ms

  • 第4条のステートメント:3710ms

上記のクエリのためのことに注意してください:

  • 最初の文と第二文の比較:選択*速度を使用して選択し、IDの代わりには3倍に増加しました

  • 比較条2及び3声明:数十ミリ秒の速度差

  • 第3条及び第4条文文の比較:増加の速度からID恩恵を選択し、3倍に増加し、第3条のステートメントのクエリの速度

オリジナルの一般的なクエリーの方法に比べてこのように速く、数回になります。

Idは、最適化を使用して定義しました

これはされたデータテーブルIDことを前提として連続的に増加するが、その後、私たちはページとクエリクエリの数、あなたが間のIDを使用することができますし、照会するレコードの数に基づいてクエリの範囲のIDを計算することができます。

select * from orders_history where type=2
and id between 1000000  and  1000100 limit 100;

問合せ時間:15msのが12msののて9ms

大幅に検索速度を最適化することができます。このクエリは、実質的に数十ミリ秒以内に完了することができます。使用する唯一の制限は、IDの状況を明確に認識しているが、タイムテーブル作成のほとんどは、ページングクエリのために利便性の多くをもたらした基本的なidフィールドを追加します。

また、書き込みの別の種類があるかもしれません。

select * from orders_history where id >= 1000001 limit 100;

もちろん、関連するマルチテーブルのクエリは、クエリするIDテーブルクエリの他のセットを使用する場合、このアプローチがしばしば使用され、照会する方法で使用することができます。

select * from orders_history where id in
(select order_id from trade_2 where goods = 'pen')
limit 100;

このように、クエリは注意する:いくつかのMySQLのバージョンは、IN句での制限の使用をサポートしていません。

一時テーブルの使用を最適化

それは、最適化を照会するために属していないこのように、ここでの方法来ます。

質問IDは最適化を定義したために、あなたは、このような時に使用履歴テーブルとして、idが連続的に増加するが、いくつかのシナリオでされて必要がある、またはIDページングを記録するために一時記憶テーブルを使用することを検討して、データの問題が欠落したときに登場し、クエリでページングを使用するためのID。これは、大幅にデータの数千万の場合は特に量、伝統的なページングクエリの速度を向上させることができます。

データテーブルのID説明

通常の状況下では、IDフィールドを追加することを余儀なくデータベース内のテーブルの確立がので問い合わせを容易にするために、各テーブルにインクリメントされます。

そのような注文や他の非常に大規模なデータベースのようなデータの量は、一般に、サブライブラリーサブテーブルになる場合。この時間は、一意の識別子IDデータベースとして推奨されていないが、固有IDを生成するために、分散型発電機の高い並行性を使用する必要があり、データテーブル内の追加フィールドを使用することは、固有の識別子を格納します。

最初の使用範囲クエリ位置決めID(またはインデックス)を使用し、その後数回クエリの速度を向上させることができるデータを見つけるためにインデックスを使用します。つまり、最初のIDを選択し、*選択しています。

おすすめ

転載: blog.51cto.com/14230003/2429776