MySQLデータ最適化方法の要約

データベース研究ノート記録

1.最も適切なフィールド属性を選択します

1.フィールド幅はできるだけ小さくする必要があります

MySQLは大量のデータへのアクセスを十分にサポートできますが、一般的に言えば、データベース内のテーブルが小さいほど、クエリの実行速度は速くなります。したがって、テーブルを作成するときは、パフォーマンスを向上させるために、テーブル内のフィールドの幅をできるだけ小さく設定できます。
たとえば、郵便番号フィールドを定義するときに、CHAR(255)に設定すると、明らかにデータベースに不要なスペースが追加され、CHAR(6)が非常に優れている可能性があるため、VARCHARの使用も冗長になります。タスクを完了しました。 。同様に、可能であれば、BIGINの代わりにMEDIUMINTを使用して整数フィールドを定義する必要があります。

2.フィールドをNULL以外に設定してみてください

効率を改善する別の方法は、可能な場合はフィールドをNOTNULLに設定して、将来クエリを実行するときにデータベースがNULL値を比較する必要がないようにすることです。

3.分類データをENUMタイプに設定します

「province」や「gender」などの一部のテキストフィールドでは、ENUMタイプとして定義できます。MySQLでは、ENUMタイプは数値データとして扱われ、数値データはテキストタイプよりもはるかに高速に処理されるためです。このようにして、データベースのパフォーマンスを向上させることができます。

2つ目は、サブクエリ(Sub-Queries)の代わりにjoin(JOIN)を使用することです。

サブクエリを使用すると、論理的に一度に複数のステップを完了する必要がある多くのSQL操作を完了することができます。同時に、トランザクションやテーブルのロックアップを回避でき、記述も簡単です。ただし、場合によっては、サブクエリをより効率的な結合(JOIN)に置き換えることができます。たとえば、注文レコードを持たないすべてのユーザーをフェッチする場合、次のクエリを使用して完了できます。

SELECT*FROM customer_info
WHERE customer_id  NOT IN (SELECT customer_id FROM sales_info)

JOIN ...を使用してこのクエリを完了すると、速度が大幅に向上します。特に、sales_infoテーブルのCustomerIDにインデックスがある場合、パフォーマンスは向上します。クエリは次のとおりです。

SELECT*FROM customer_info
LEFT JOIN sales_info ON customer_info.customer_id=sales_info.customer_id
WHERE sales_info.customer_id IS NULL

JOINがより効率的である理由は、MySQLがこの論理的な2ステップのクエリを完了するためにメモリ内に一時テーブルを作成する必要がないためです。

3つ目は、手動で作成した一時テーブルの代わりにユニオン(UNION)を使用する

UNION演算子は、2つ以上のSELECTステートメントの結果セットを組み合わせるために使用されます。
UNION内の各SELECTステートメントには、同じ数の列が必要であることに注意してください。列にも同様のデータ型が必要です。同時に、各SELECTステートメントの列の順序は同じである必要があります。

MySQLはバージョン4.0以降UNIONクエリをサポートしています。一時テーブルを必要とする2つ以上のSELECTクエリを1つのクエリに組み合わせることができます。クライアントのクエリセッションが終了すると、一時テーブルが自動的に削除され、データベースが整頓されて効率的になるようになります。UNIONを使用してクエリを作成する場合、複数のselectステートメントを接続するためのキーワードとしてUNIONを使用するだけで済みます。

第4に、トランザクション(トランザクション)を使用して、データの整合性を確保し、速度を向上させます

サブクエリ(Sub-Queries)、結合(JOIN)、およびユニオン(UNION)を使用してさまざまなクエリを作成できますが、の1つまたは少数のSQLステートメントだけですべてのデータベース操作を完了できるわけではありません。多くの場合、ある種の作業を完了するには、一連のステートメントを使用する必要があります。ただし、この場合、ステートメントブロック内の特定のステートメントが正しく実行されないと、ステートメントブロック全体の動作が不確実になります。特定のデータを2つの関連するテーブルに同時に挿入する場合、次のような状況が発生する可能性があるとします。最初のテーブルが正常に更新された後、データベースが突然予期しないように表示され、2番目のテーブルの操作が実行されなくなります。完了、このように、それは不完全なデータを引き起こし、データベース内のデータを破壊することさえあります。
この状況を回避するには、トランザクションを使用する必要があります。その役割は次のとおりです。

  1. ステートメントブロック内のすべてのステートメントが成功したか、すべてが失敗しました。つまり、データベース内のデータの整合性と整合性を維持できます。BEGINキーワードで始まり、COMMITキーワードで終わります。その間、SQL操作は失敗し、ROLLBACKコマンドはデータベースをBEGINが開始される前の状態に復元できます。
  2. トランザクションのもう1つの重要な機能は、複数のユーザーが同じデータソースを同時に使用する場合、データベースをロックする方法を使用して、ユーザーに安全なアクセス方法を提供できることです。これにより、ユーザーの操作が他のユーザーに干渉されないようにすることができます。ユーザー。。
  3. トランザクションの形式で記述されているため、データベースに複数回接続する必要がないため、パフォーマンスが向上し、追加、削除、チェック、および変更の速度が向上します。
BEGIN; //或start transaction
INSERT INTO salesinfo SET CustomerID=14;//语句1
UPDATE inventory SET Quantity=11 WHERE item='book';//语句2
COMMIT;
//若失败如 
//if(update失败) {rollback} 

一般的な例は銀行振込です。口座Aは1億(T1)を口座Bに送金します。この種の取引の過程で、考える価値のあるいくつかの質問があります:
上記の取引を同時に確実にする方法

アカウントAの合計金額が1億減少し、アカウントBの合計金額が1億増加しますか?A
AとCが同時にアカウントの場合、アカウントトランザクション(T2)の場合、2つのトランザクションを互いに独立して行うにはどうすればよいですか?I
トランザクションがデータベースの突然の崩壊で完了した場合、データベースに保存されているトランザクションデータを確実に成功させるにはどうすればよいですか?D
は、多数のトランザクションをサポートしながら、データの正当性をどのように保証できますか(お金が作成されたり、空中に消えたりすることはありません)。C.
トランザクションが正常かつ確実に実行されるようにするには、データベースは上記の4つの問題を解決する必要があります。これがトランザクションの誕生の背景です。上記の4つの問題を解決できます。これに対応して、4つの主要な特性があります。すなわちACID

  • Atomicity:トランザクションが完了またはキャンセルされました。トランザクションがクラッシュした場合、状態はトランザクションの前に戻ります(トランザクションはロールバックします)。それらは切り離せません。
  • 分離:2つのトランザクションT1とT2が同時に実行される場合、
    誰が最初にT1とT2を終了するかに関係なく、トランザクションT1とT2の最終結果は同じです。隔離はロックすることで解決できます。
  • 耐久性:トランザクションがコミットされると、何が起こっても(データベースのクラッシュやエラーなど)、データをデータベースに保存できます。抵抗できない理由でクラッシュした後にデータベースを再起動すると、コミットされたトランザクションのためにデータがディスクに保存され、コミットされていないトランザクションのために対応するデータがロールバックされます。
  • 一貫性:データベースに書き込むことができるのは、(リレーショナル制約と機能制約による)正当なデータのみです。システム内の薄い空気からお金が発生したり消えたりしないようにするには、原子性と分離に依存します。

データベースは、トランザクションログを通じてこの目標を達成します

  • 更新するたびにディスクに書き込むと、データがランダムであるため、ランダムIOが多く発生し、パフォーマンスが非常に低下します。
  • 各更新の直後にディスクに書き込まない場合、データベースがクラッシュすると、データは失われます

妥協点は次のとおりです。

  • データの変更は、トランザクションログの形式で時系列でログバッファに追加され、特定のアルゴリズムによってトランザクションログに書き込まれます。これはシーケンシャルIOであり、パフォーマンスが向上します
    。トランザクションログはデータマネージャによって解析されます。特定のアルゴリズムで記述されています。プレート

トランザクションの分離レベルの概念もあります。パフォーマンスを向上させるために、さまざまなレベルの分離ロックをさまざまなビジネスに追加できます。

5、テーブルをロックします

トランザクションはデータベースの整合性を維持するための非常に優れた方法ですが、その排他性のために、特に大規模なアプリケーションシステムでは、データベースのパフォーマンスに影響を与えることがあります。トランザクションの実行中はデータベースがロックされるため、他のユーザーリクエストはトランザクションが終了するまで一時的にしか待機できません。データベースシステムを使用するユーザーが少ない場合、トランザクションの影響は大きな問題にはなりませんが、eコマースWebサイトにアクセスするなど、データベースシステムに同時にアクセスするユーザーが数千人いる場合は、より深刻な応答遅延が発生します。

実際、場合によっては、テーブルをロックすることでパフォーマンスを向上させることができます。次の例では、テーブルをロックする方法を使用して、前の例のトランザクション関数を完了します。

LOCK TABLE inventory WRITE SELECT Quantity FRO Minventory WHERE Item='book';
//一些计算写在这里
UPDATE inventory SET Quantity=11 WHERE Item='book';
UNLOCK TABLES

ここでは、selectステートメントを使用して初期データをフェッチし、いくつかの計算を通じて、updateステートメントを使用して新しい値をテーブルに更新します。WRITEキーワードを含むLOCKTABLEステートメントは、UNLO​​CK TABLESコマンドが実行される前に、インベントリーを挿入、更新、または削除するための他のアクセスがないことを保証できます。

6、外部キーを使用する

テーブルをロックする方法は、データの整合性を維持できますが、データの関連性を保証することはできません。現時点では、外部キーを使用できます。

たとえば、外部キーを使用すると、すべての販売記録が既存の顧客を指していることを確認できます。ここで、外部キーは、customerinfoテーブルのCustomerIDをsalesinfoテーブルのCustomerIDにマップできます。有効なCustomerIDのないレコードは、更新されたり、salesinfoに挿入されたりすることはありません。

 
CREATE TABLE customerinfo( CustomerID INT NOT NULL,PRIMARYKEY(CustomerID)) TYPE=INNODB;
CREATE TABLE salesinfo( SalesID INT NOT NULL,CustomerID INT NOT NULL,PRIMARYKEY(CustomerID,SalesID),
FOREIGN KEY(CustomerID)REFERENCES customerinfo(CustomerID)ON DELETE CASCADE)TYPE=INNODB;

例のパラメータ「ONDELETECASCADE」に注意してください。このパラメーターは、customerinfoテーブルの顧客レコードが削除されると、salesinfoテーブルの顧客に関連するすべてのレコードも自動的に削除されることを保証します。
MySQLで外部キーを使用する場合は、テーブルを作成するときに、テーブルのタイプをトランザクションセーフなInnoDBタイプとして定義することを忘れないでください。このタイプは、MySQLテーブルのデフォルトタイプではありません。定義の方法は、TYPE = INNODBをCREATETABLEステートメントに追加することです。例に示すように。

セブン、インデックスを使用する

インデックス作成では、辞書に配置された最初の文字A、B、C ...を使用して理解しやすくすることができます。たとえば、データにインデックスを追加すると、それぞれの代わりに「最初の文字」に基づいてデータをすばやく見つけることができます。 item検索に移動します。
特に、クエリステートメントにMAX()、MIN()、およびORDERBYコマンドが含まれている場合、インデックスを使用すると、データベースのパフォーマンスを大幅に向上させることができます。

どのフィールドにインデックスを付ける必要がありますか?

一般的に、インデックスは、JOIN、WHERE判定、およびORDERBYソートに使用されるフィールドに基づいて作成する必要があります。
注:繰り返し値が多数含まれているデータベース内のフィールドにインデックスを付けないようにしてください。ENUMタイプのフィールドの場合、重複する値が多数存在する可能性が非常に高くなります。

インデックスの詳細な操作と、単一列インデックスと複合インデックスの違いについては、次のリンク(Program Ape Interviewの頻繁な試験)
https://blog.csdn.net/S_ZaiJiangHu/article/details/114420976を参照してください。

8.最適化されたクエリステートメント

ほとんどの場合、インデックスを使用するとクエリの速度を向上させることができますが、SQLステートメントが適切に使用されていない場合、インデックスはその本来の役割を果たすことができません。

以下は注意が必要ないくつかの側面です。

まず、同じタイプのフィールド間で操作を比較するのが最善です。

MySQL 3.23以前は、これは必要条件でさえありました。たとえば、インデックス付きINTフィールドをBIGINTフィールドと比較することはできませんが、特別な場合として、CHAR型フィールドとVARCHAR型フィールドのフィールドサイズが同じである場合、それらを比較することができます。

次に、インデックス付きフィールドの操作に関数を使用しないようにします。

たとえば、YEAE()関数がDATE型フィールドで使用されている場合、インデックスは正常に機能しません。したがって、次の2つのクエリは同じ結果を返しますが、後者は前者よりもはるかに高速です。

第3に、文字フィールドを検索するときに、LIKEキーワードとワイルドカードを使用することがあります。このアプローチは単純ですが、システムパフォーマンスも犠牲になります。
たとえば、次のクエリはテーブル内のすべてのレコードを比較します。

SELECT * FROMbooks

WHEREnamelike "MySQL%"

ただし、次のクエリに切り替えると、結果は同じになりますが、速度ははるかに速くなります。

SELECT * FROMbooks

WHEREname> =“ MySQL” andname <"MySQM”

最後に、MySQLがクエリで自動型変換を実行しないように注意する必要があります。これは、変換プロセスによってインデックスも機能しなくなるためです。

おすすめ

転載: blog.csdn.net/S_ZaiJiangHu/article/details/114414778