ディレクトリ
1、テストデータを作成します
表1.1ビルド
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c_user_id` varchar(36) NOT NULL DEFAULT '' COMMENT '用户Id',
`c_name` varchar(22) NOT NULL DEFAULT '' COMMENT '用户名',
`c_province_id` int(11) NOT NULL COMMENT '省份Id',
`c_city_id` int(11) NOT NULL COMMENT '城市Id',
`create_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`c_user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=100000001 DEFAULT CHARSET=utf8mb4;
テストデータを挿入1.2
図2に示すように、一般的なページングクエリー:限界
2.1制限について
シンプルな制限句を使用して、一般的なページングクエリを達成することができます。次の文の制限句:
SELECT *
FROM table
LIMIT [offset,] rows | rows OFFSET offset;
LIMIT句はSELECTステートメントによって返されるレコードの数を指定するために使用することができます。以下の点に注意してください。
- 最初の引数は、最初に戻ってからの注目のオフセット行指定
0
の開始を。 - 第2のパラメータは、リターンの行の最大数を指定します。
- 唯一つのパラメータを考える:最大行数、そのリターンを示します。
- 二番目のパラメータに-1すべての行が設定されたレコードへの一方の端からのオフセットを取得します。
- オフセット0(代わりに、1の)最初の行です。
2.2例
select * from t_user limit 1000, 10;
記事は、テーブルt_userから文を照会しますoffset:1000
(記事1010年のデータに条1001年、つまり、データの開始後10 1001<=id<=1010
)。
上記のデフォルトに対応するマスターキー(通常はID)ソート結果を使用して、データテーブルのレコード:
select * from t_user order by limit 1000, 10;
2.3テスト
1つのレコードのテストクエリは、時間の量に影響を与えます
直接ノーショット、およびそれの結果を書き込みます:
测试语句 三次执行分别耗时(ms)
select * from t_user limit 1000, 1; 15 -- 15 -- 14
select * from t_user limit 1000, 10; 14 -- 15 -- 15
select * from t_user limit 1000, 100; 15 -- 15 -- 15
select * from t_user limit 1000, 1000; 17 -- 16 -- 16
select * from t_user limit 1000, 10000; 168 -- 158 -- 158
select * from t_user limit 1000, 100000; 1159 -- 1559 -- 1479
観点から、クエリ時間をフォローアップし、いくつかの試み、問い合わせレコード量が増加するにつれて1000レコードボリューム、クエリ時間ギャップよりも低くされていないで、クエリ時に、ほぼ一定であり、それはかかる時間はますますなりもっと。
2つの試験クエリは時間の影響を相殺します
测试语句 三次分别耗时
select * from t_user limit 100, 100; 16 -- 16 -- 15
select * from t_user limit 1000, 100; 15 -- 17 -- 14
select * from t_user limit 10000, 100; 18 -- 17 -- 17
select * from t_user limit 100000, 100; 42 -- 42 -- 42
select * from t_user limit 1000000, 100; 761 -- 727 -- 762
特にオフセットクエリクエリの増加、オフセット後100,000を超える、クエリ時間の急激な増加です。
このページングクエリは、データベースから最初のレコードのスキャンを開始しますより後方ので、低速のクエリの速度が、より多くのデータのクエリは、クエリが全体の速度が遅くなります。
図3に示すように、サブ照会最適化限界の使用
(1)select * from t_user limit 100000, 1;
(2)select id from t_user limit 100000, 1;
(3)select * from t_user where id >= (select id from t_user limit 100000, 1) limit 100;
(4)select * from t_user limit 100000, 100;
3つのテストクエリ時間以上の4文は以下の通りでした。
(1) 43 -- 43 -- 41
(2) 27 -- 26 -- 25
(3) 27 -- 27 -- 26
(4) 44 -- 41 -- 43
なお、上記のクエリのために:
-
選択IDの代わりに、選択*を使用して、クエリ時間によって:最初の文と第二文の比較
-
クエリの速度以下:2文と文の第3条の比較
-
第3条の比較及び第4条文の声明:増加の速度から選択したID利益、声明も増加したクエリの速度の第3条
クエリ方法の一般的な限界と比較して、このようにして、データクエリの速度を加速します。
4、ID定義最適化
これはされたデータテーブルIDことを前提として連続的に増加するが、その後、私たちはページやクエリのクエリの数は、あなたが間、およびクエリにIDを使用できるレコードの数に基づいて、クエリの範囲のIDを計算することができます。
测试语句 耗时(ms)
(优化)select * from t_user where id between 100000 and 1000100 limit 100; 14 -- 14 -- 14
(原始)select * from t_user limit 100000, 100; 42 -- 41 -- 41
为了对比,将修改数据:
(优化)select * from t_user where id between 10000000 and 100000100 limit 100; 16 -- 13 -- 14
(原始)select * from t_user limit 10000000, 100; 4605 --4632--4622
大幅に検索速度を最適化することができます。このクエリは、実質的に数十ミリ秒以内に完了することができます。使用する唯一の制限は、IDの状況を明確に認識しているが、タイムテーブル作成のほとんどは、クエリをページングするために利便性の多くをもたらした基本的なidフィールドを追加します。
書き込みに別の方法があります:
select * from t_user where id >= 10000001 limit 100;
もちろん、関連するマルチテーブルクエリは、クエリにIDテーブルクエリの他のセットを使用する場合、このアプローチがしばしば使用され、クエリの方法で使用することができます。
eg:select * from t_user where id in (select id from t_user2 where city='Beijing') limit 100;
このようにノートにクエリ:いくつかのMySQLのバージョンは、IN句での制限の使用をサポートしていません。
5、一時テーブルの使用を最適化
それは、クエリの最適化に属していないこのように、ここでの方法来ます。
最適化を定義した質問IDの、あなたは、idが連続的に増加するが、データの問題が欠落したときに、レコードIDページングに一時記憶テーブルを使用することを検討して登場し、またはそのような使用履歴テーブルなどいくつかのシナリオ、にされて必要クエリでページングを使用するためのID。これは、大幅にデータの数千万の場合は特に量、伝統的なページングクエリの速度を向上させることができます。(これは、テストする必要があります)
図6に示すように、データテーブルIDの説明
通常の状況下では、IDフィールドを追加することを余儀なくデータベース内のテーブルの確立は、各テーブルにインクリメントされるので、照会を容易にします。
そのような注文や他の非常に大規模なデータベースのようなデータの量は、一般に、サブライブラリーサブテーブルになる場合。この時間は、一意の識別子IDデータベースとして推奨されていないが、固有IDを生成するために、分散型発電機の高い並行性を使用する必要があり、データテーブル内の追加フィールドを使用することは、固有の識別子を格納します。
ID(またはインデックス)を位置決めする第1の使用範囲クエリを使用し、その後、数回のクエリ速度を向上させることができるデータを見つけるためにインデックスを使用します。すなわち、第1の選択IDは、その後、*選択します。