データベースクエリのテーブルからのレコードの数万人の必要性は、すべて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を選択し、*選択しています。