Mysql は大規模なデータ テーブルをどのように処理しますか?次の記事では、Mysql ビッグ データ テーブル処理ソリューションを紹介します。お役に立てば幸いです。
ビジネス データベース テーブル内のデータがますます増え、あなたと私が次のような状況に遭遇したとします。同様のシナリオで、この問題を一緒に解決しましょう
行データのクエリ方法: テーブル内にどれだけのデータがあるかをクエリするときに通常使用する古典的な SQL ステートメントは次のとおりです。
select count(*) from tableディスク容量
select table_schema as '数据库', table_name as '表名', table_rows as '记录数', truncate(data_length/1024/1024, 2) as '数据容量(MB)', truncate(index_length/1024/1024, 2) as '索引容量(MB)' from information_schema.tables order by data_length desc, index_length desc;
select table_schema as '数据库', table_name as '表名', table_rows as '记录数', truncate(data_length/1024/1024, 2) as '数据容量(MB)', truncate(index_length/1024/1024, 2) as '索引容量(MB)' from information_schema.tables where table_schema='mysql' order by data_length desc, index_length desc;クエリの結果は次のとおりです:
推奨データディスク使用量に占める量は 70% 以内です。同時に、急速に増大する一部のデータについては、データのアーカイブに大規模で遅いディスクの使用を検討できます (アーカイブについては、プラン 3 を参照してください)
インスタンス容量MySQL は、スレッドベースのサービス モデルであるため、同時実行性が高い一部のシナリオでは、単一インスタンスではサーバーの CPU リソースを完全に活用できず、スループットが mysql 層でスタックします。ビジネスに基づいて独自のインスタンス モードを検討できます。問題の原因
B
ツリー構造のレベルが高くなり、データをクエリする際に多くのディスク IO が必要となるため、クエリのパフォーマンスが低下するためです。B ツリーに保存できるデータ量をまだ覚えていますか?
InnoDB ストレージ エンジンの最小ストレージ単位はページであり、ページのサイズは 16k
です。B ツリーの葉にはデータが格納され、内部ノードにはキー値のポインターが格納されます。索引構成表は、非リーフ・ノードとポインターの二分検索方法によってデータがどのページにあるかを判別し、データ・ページに移動して必要なデータを見つけます。
B ツリーの高さが
の場合、1 つのルート ノードと複数のリーフ ノードがあるとします。この B ツリーに格納されるレコードの総数は、= ルート ノード ポインターの数 * 1 つのリーフ ノードに記録される行の数です。
レコードの行のデータ サイズが 1k の場合、1 つのリーフ ノードに格納できるレコードの数 =16k/1k =16.
いくつポインタは非リーフノードに格納されますか?主キー ID は bigint 型で、長さは 8 バイト
であると仮定します (
単一テーブル内のデータが多すぎてクエリが遅いという問題を解決する方法
这里提供了三种解决方案,包括数据表分区,分库分表,冷热数据归档 了解完这些方案之后大家可以选取适合自己业务的方案
为什么要分区:表分区可以在区间内查询对应的数据,降低查询范围 并且索引分区 也可以进一步提高命中率,提升查询效率
分区是指将一个表的数据按照条件分布到不同的文件上面,未分区前都是存放在一个文件上面的,但是它还是指向的同一张表,只是把数据分散到了不同文件而已。
我们首先看一下分区有什么优缺点:
表分区有什么好处?
与单个磁盘或文件系统分区相比,可以存储更多的数据。
对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有关的分区,很容易地删除那些数据。相反地,在某些情况下,添加新数据的过程又可以通过为那些新数据专门增加一个新的分区,来很方便地实现。
一些查询可以得到极大的优化,这主要是借助于满足一个给定WHERE语句的数据可以只保存在一个或多个分区内,这样在查找时就不用查找其他剩余的分区。因为分区可以在创建了分区表后进行修改,所以在第一次配置分区方案时还不曾这么做时,可以重新组织数据,来提高那些常用查询的效率。
涉及到例如SUM()和COUNT()这样聚合函数的查询,可以很容易地进行并行处理。这种查询的一个简单例子如 “SELECT salesperson_id, COUNT (orders) as order_total FROM sales GROUP BY salesperson_id;”。通过“并行”,这意味着该查询可以在每个分区上同时进行,最终结果只需通过总计所有分区得到的结果。
通过跨多个磁盘来分散数据查询,来获得更大的查询吞吐量。
表分区的限制因素
一个表最多只能有1024个分区。
MySQL5.1中,分区表达式必须是整数,或者返回整数的表达式。在MySQL5.5中提供了非整数表达式分区的支持。
如果分区字段中有主键或者唯一索引的列,那么多有主键列和唯一索引列都必须包含进来。即:分区字段要么不包含主键或者索引列,要么包含全部主键和索引列。
分区表中无法使用外键约束。
MySQL的分区适用于一个表的所有数据和索引,不能只对表数据分区而不对索引分区,也不能只对索引分区而不对表分区,也不能只对表的一部分数据分区。
在进行分区之前可以用如下方法 看下数据库表是否支持分区哈
mysql> show variables like '%partition%'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | have_partitioning | YES | +-------------------+-------+ 1 row in set (0.00 sec)
为什么要分表:分表后,显而易见,单表数据量降低,树的高度变低,查询经历的磁盘io变少,则可以提高效率
mysql 分表分为两种 水平分表和垂直分表
分库分表就是为了解决由于数据量过大而导致数据库性能降低的问题,将原来独立的数据库拆分成若干数据库组成 ,将数据大表拆分成若干数据表组成,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。
定义:数据表行的拆分,通俗点就是把数据按照某些规则拆分成多张表或者多个库来存放。分为库内分表和分库。 比如一个表有4000万数据,查询很慢,可以分到四个表,每个表有1000万数据
定义:列的拆分,根据表之间的相关性进行拆分。常见的就是一个表把不常用的字段和常用的字段就行拆分,然后利用主键关联。或者一个数据库里面有订单表和用户表,数据量都很大,进行垂直拆分,用户库存用户表的数据,订单库存订单表的数据
缺点:垂直分隔的缺点比较明显,数据不在一张表中,会增加join 或 union之类的操作
知道了两个知识后,我们来看一下分库分表的方案
分割する前に、データ量を見積もります。たとえば、user テーブルには 4,000 万のデータがあり、データを 4 つのテーブル user1 user2 uesr3 user4 に分割する必要があります。 たとえば、id = 17, 17 modulo 4 は 1 に を加えたものであるため、このデータは user2 テーブルに格納されます。
注: Auto_increment は、水平分割後にテーブルから削除する必要があります。このときのIDはID自己増加テンポラリテーブルを利用するか、redis incrメソッドを利用して取得できます。 ###############アドバンテージ: データはさまざまなテーブルに均等に分割されており、ホットな問題が発生する可能性は非常に低くなります。
デメリット: 将来的なデータの拡張や移行が難しくなる データ量が多くなると、これまで4テーブルに分割されていたものが8テーブルに分割され、モジュロ値が変化し、再度データ移行を行う必要があります。
2.range range スキーム
データを範囲ごとに分割します。つまり、特定の範囲内の注文が特定のテーブルに格納されます。たとえば、user1 テーブルには id=12 が格納され、user2 テーブルには id=1300 万が格納されます。利点: 将来のデータ拡張に役立つ
欠点: ホット データが 1 つのテーブルに存在する場合、一方のテーブルにはプレッシャーがかかり、もう一方のテーブルにはプレッシャーがかかります。ゲージに圧力はかかりません。
上記の 2 つのソリューションには欠点もありますが、補完的なものであることがわかりました。では、これら 2 つのソリューションを組み合わせるとどうなるでしょうか?3. ハッシュ係数と範囲スキームの組み合わせ
下の図に示すように、グループ group には 0 から 4,000 万までの ID を持つデータが格納されていることがわかります。 、DB0 という 3 つのデータベースがあります。 DB1、DB2、DB0 には 4 つのデータベースがあり、DB1 と DB2 には 3 つのデータベースがあります。1. トランザクションの問題
余分なデータ管理の負担、最も明白なのはデータの配置の問題と、データの追加、削除、変更の繰り返しの実行です。と query , これらはアプリケーションを通じて解決できますが、必然的に追加の論理演算が発生します。たとえば、ユーザー スコアを記録するユーザー データ テーブル userTable の場合、ビジネスでは最高 100 のスコアを見つける必要があります。テーブルを分割する前に、 order by ステートメントは実行できますが、テーブルを分割した後、分割された各テーブルの上位 100 人のユーザー データを検索し、データをマージして結果を取得するには、n 回の order by ステートメントが必要になります。
ホット アーカイブとコールド アーカイブが必要な理由: 実際、理由は 2 番目のオプションと同様で、単一テーブル内のデータ量が減少し、ツリーの高さが低くなると、クエリで発生するディスク IO が減少し、効率が向上します。 たとえば、ビジネス データにホットとコールドの明確な区別がある場合、過去 1 週間または過去 1 か月のデータのみを表示する必要があります。この場合、今週と月間のデータをホットデータ、残りのデータをコールドデータと呼びます。その後、コールド データを他のデータベース テーブルにアーカイブして、ホット データの運用効率を向上させることができます。
アーカイブ テーブルを作成します 原則として、作成したアーカイブテーブルは元のテーブルと一致している必要があります。
アーカイブテーブルデータの初期化
ビジネス増分データ処理プロセス
トライアルシナリオ | 利点 | 欠点 | |
---|---|---|---|
1. 大量のデータ 2 。クエリシナリオは特定の領域のみ 3. 結合クエリシナリオは存在しない | パーティショニングとテーブルパーティショニングとは、データテーブルに対応するファイルを物理的に分割することです。 sql | など、テーブル分割後の以前の業務ロジックに影響を与える業務は、対応するオブジェクトを作成するため、一定のオーバーヘッドが発生し、分割されたデータの集計にも時間がかかり、利用範囲が制限される | |
データ量が多く、区別できない | ホット領域とコールド領域の境界が明確でないデータに適しており、後続の同様のデータに対してもこの方法を使用できます。クエリ挿入の効率を高めるために、大きなテーブルを小さなテーブルに分割する | 大きなデータ テーブルが徐々に増加する場合、対応するデータベース テーブルの数がますます必要になり、各テーブルをテーブルに分割する必要があります。間隔の分割は比較的固定されており、後続の単一テーブルのデータ量が増加すると、パフォーマンスにも影響します。実装の複雑さは 3 番目のソリューションよりも複雑で、全体をテストする必要があります。コーディング層で処理され本来の業務に影響を与える; | |
データ量が多く、コールドデータのホット パーティションが明らかである; コールド データの使用頻度が非常に低い; | データ移行のプロセスはビジネスへの影響が少なく、開発量もコストも削減されます。 | テーブル分割ルールを確認する必要があります |
ということで、ここで私が話したいことは終わりに近づいてきましたが、もし何か間違っていることや疑問に思っていることがあれば、ぜひアドバイスをいただければ幸いです。
[関連する推奨事項:
mysql ビデオ チュートリアル以上がMysql は大規模なデータ テーブルをどのように処理しますか?ソリューションの共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。