Mysql ステートメント分析、ストレージ エンジン、インデックスの最適化、その他の詳細

高性能Mysqlの読書メモ

Mysql ストレージ エンジン

Mysql のデフォルト ストレージ エンジン: Innodb

Mysql5.1 バージョンより前のデフォルトのストレージ エンジンはMyISAMです。

ストレージ エンジンの複数同時実行制御の違い (MVCC):

InnoDB:

4 つの分離レベルを使用してトランザクションをサポート

  1. コミットされていない読み取り (コミットされていない読み取り)

    最高の同時実行性。トランザクション内の変更が送信された場合でも、他のトランザクションに表示されます

  2. コミットされた読み取り

    ほとんどのデータベース管理システムのデフォルトの分離レベルはこれで (Mysql はそうではありません)、コミットされたトランザクションの変更のみが表示されます。

    2 つの実行の結果が同じである可能性がありますが、結果は異なります

  3. RepeatTable 読み取り (反復可能な読み取り)
    Mysql トランザクションの既定の分離レベル。同じトランザクションの複数の読み取り結果が一貫していることを確認する

  4. シリアライズ可能 (シリアライズ可能)

最高の分離レベル、最低の同時実行性では、データの各行を読み取るときに共有ロックが追加されます。

MyISAM:

トランザクションをサポートしていません

パフォーマンスに関しては、MyISAM はいくつかの特定のシナリオで優れたパフォーマンスを発揮します。デザインはシンプルで、データはコンパクトな形式で保存され、挿入速度は非常に高速です

Mysql 自動コミット

Mysq はデフォルトで自動コミット モードを使用します。つまり、トランザクションが明示的に開かれていない場合、各クエリはコミット操作を実行するトランザクションとして扱われます。現在のリンクでは、AUTOCOMMIT 変数を設定することで、自動コミット モードを有効または無効にすることができます。(*10)

コマンド set autocommit= 0/1 (1: 有効。0: 無効) を渡すことができます。

Mysql パフォーマンス分析

Mysql クエリをログ ファイルにキャプチャする

long_query_time=0 を設定すると、すべてのクエリをキャプチャできます

show variables like 'slow_query_log'; -- 显示是否开启慢sql日志
SET GLOBAL slow_query_log_file	-- 指定慢查询日志存储文件的地址和文件名。
SET GLOBAL log_queries_not_using_indexes	-- 无论是否超时,未被索引的记录也会记录下来。
SET SESSION long_query_time	-- SQL 执行超过这个阈值(秒)将被记录在日志中。
SET SESSION min_examined_row_limit	-- 慢查询仅记录扫描行数大于此参数的 SQL。

スロー クエリ ログを分析するためのツールpt-query-digestがあります.半分のケースでは、正しく動作するためにスロー クエリ ログをパラメーターとしてpt-query-digestに渡すだけで済みます。彼はクエリの分析レポートを印刷します。

Mysql パフォーマンス分析ツール

  1. New Relic (プロファイリングのためにアプリケーションにプラグインされます)
  2. マスキット
  3. Super Smark (ストレス テストとロード生成を提供できます。テスト データをデータベースにロードし、生成されたデータの蓄積をサポートしてデータ テーブルを埋めることができます)
プロフィールを表示

ステートメント分析ツール

SHOW PROFILEコマンドは、Mysql5.1 以降のバージョンで導入されました。set profiling=1デフォルトでは無効で、次の方法で有効にできます

サーバー上でツールによって実行されるすべてのステートメントは、経過時間とクエリ実行ステータスの変化に関するその他の関連データを検出します。

クエリ コマンドがサーバーに送信されると、分析情報が一時レコード テーブルに記録されます。

使い方:

コマンドshow PROFILESを使用して、記録されたすべての実行ステートメントを表示します。各ステートメントにはコード Query_id があります。詳細を表示するステートメントを見つけます。Query_id を取得します。

順番に

show profile for QUERY queri_id(上で取得したQuery_id);

以下に示すように

[外部リンクの画像転送に失敗しました。ソース サイトにアンチリーチング メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-LqM2b4AX-1659795260686)(/Users/xujiangtao/Desktop/screenshot 2022-08-04 13.00.03.png) ]

[外部リンクの画像転送に失敗しました。ソース サイトにアンチリーチング メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-v5QaRYS2-1659795260687) (/Users/xujiangtao/Desktop/screenshot 2022-08-04 13.01.47.png) ]

ステータスを表示

操作の数を示すいくつかのカウンターを返します。たとえば、次の SQL ステートメントで一時テーブルが使用された回数をすばやく表示できます。インデックスを使用した読み取り操作 (*84)

SHOW STATUS WHERE Variable_name	LIKE 'Handler%' OR Variable_name LIKE 'Create%'

[外部リンクの画像転送に失敗しました。ソース サイトには盗難防止リンク メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-QZWjwCSH-1659795260687) (/Users/xujiangtao/Desktop/screenshot 2022-08- 04 13.12.53.png) ]

SHOW GLOBAL STATUSを使用して、グローバル ステータスを表示することもできます。

最適化されたデータ型を選択する

注意点

  1. 通常、小さい方のデータ型は
  2. シンプルなのがいい、例えば整形の方がストリングよりも運用コストが安い
  3. NULL 値を避けるようにしてください

It is best to specify the column as NOT NULL. クエリに NULL 値が含まれている場合、Mysql の最適化がより困難になる可能性があります。NULL 許容列はインデックス、インデックス統計、および値の比較を複雑にするため、NULL 許容列はより多くのストレージ領域を使用します

整数型

整数を格納する場合は、いくつかの整数型があります。

自動インクリメントを使用することもお勧めします

  1. TINYINT範囲: (-128-127) 占有バイト数: 8
  2. SMALLINT範囲: (-8388608-8388607) 16
  3. MEDIUMINT範囲: (-128-127) 24
  4. INT範囲: (-2,147,483,648-2,147,483,647) 32
  5. BIGINT範囲: (-9223372036854775808-9223372036854775807) 64

浮動小数点型

  1. 小数

    BIGINTより大きい整数を格納でき、高精度の計算をサポート

  2. ダブル

  3. 浮く

文字列型

  1. VARCHAR

可変長文字列で、文字の長さを記録するために追加のバイトが必要です。

思考:

varchar(5) と varchar(2000) のスペース オーバーヘッドは同じですが、短い列を使用する利点はありますか?

回答: mysql が内側の布の値を保存するために固定サイズのメモリを割り当てるため、大きな利点があり、より多くのメモリを節約できます。

我们只需要分配真正需要的空间为最佳

  1. CHAR

固定長の文字を格納するために使用されます.文字を格納する場合、最後のスペースはすべて削除されます.フィールドの長さに近い値を格納するのに適しています

大きなデータ型

  1. ボルブ。(データをバイナリ形式で保存)
  2. 文章。(キャラクター形式でデータを保存)

日時型

  1. 日付時刻

YYYYMMDDHHMMSSの整数で固定形式で格納(1001~9999まで格納可能)

  1. タイムスタンプ

    1970 年から 2038 年までの年のみを保存できます。タイムスタンプを使用して時間データを保存します

インデックスベース

索引付けの利点

  1. サーバーがスキャンする必要のあるデータ量を大幅に削減
  2. サーバーが一時テーブルとソートを回避するのに役立ちます
  3. ランダム IO をシーケンシャル IO に変更可能

Bツリー

Mysql のインデックス データ型は、B-Tree データ構造を使用して実装されます

Bツリーは通常、すべての値が順番に格納されることを意味します。

索引タイプ

1. 単一値インデックス

作成方法:

create index [indexname] ON [tablename](fieldname)

最も一般的なインデックス。列のすべての値に対して B-tree インデックス ツリーを作成し、昇順で並べ替えます

2. ユニークインデックスと共同ユニークインデックス

ALTER TABLE tablename  ADD  UNIQUE [indexname] (fieldname,fieldname)

インデックス付きの列の値は一意である必要があります。ただし、null にすることができます

3.関節指数

create index [indexname] ON [tablename](fieldname,fieldname)

複数の列をインデックス値として指定し、同時に複数の列で昇順に並べ替えることができます。左端一致の原則に従う必要がある

5,000 万件を超えるレコードを含むテーブル。次の 2 つの写真を通じて、同じ sql. 1 つは共同インデックスを追加し、インデックスをカバーします。インデックスがありません。時間比較は、インデックスの最適化効率も示すことができます

ここに画像の説明を挿入

[外部リンクの画像転送に失敗しました。ソース サイトにアンチリーチング メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-qxzMDLgu-1659795260688) (/Users/xujiangtao/Desktop/screenshot 2022-08-06 21.44.42.png) ]

4. プレフィックス インデックス

ALTER TABLE table_name ADD KEY(column_name(prefix_length));

一部のフィールドの長さが非常に大きい場合、またはフィールド タイプ列に大きなスペースがある場合。接頭辞索引の使用、索引ファイルのサイズの縮小、索引提出の速度に適しています

場合によっては、非常に長い文字列にインデックスが作成されることがあります。これにより、インデックスが大きくなり、速度が低下する可能性があります。通常、最初の部分文字にインデックスを付けることができます。これにより、インデックス スペースを大幅に節約できるため、インデックスの効率が向上し、インデックスの選択も減ります (同じインデックス値に複数のデータ行が含まれる場合があります)。

order by と group by では使用できません。また、カバーインデックスとしても使用できません

5.クラスターインデックス

クラスター化インデックスに加えて、他のセカンダリ インデックスは行指针行の主キーを保存し、主キーを見つけてから、主キーのクラスター化インデックスを介してテーブルに戻り、行データを見つけます。

他のインデックスとの最大の違いは、インデックスとデータが同じ領域に存在することであり、インデックスが見つかればデータを見つけることができるということです。データ テーブルの主キーはクラスター化インデックスです。テーブルの作成時に主キーがデフォルトで指定されていない場合、mysql のストレージ エンジン Innodb は代わりに一意の空でないインデックスを選択します。そのようなインデックスがない場合、 InnoDB は主キーをクラスター化インデックスとして暗黙的に定義します。

6.カバリングインデックス

これは、追加できる特定のインデックスではなく、クエリするすべてのデータ列とクエリ条件がインデックスを使用することを意味します。主キーを使用してデータをクエリするためにテーブルに戻る必要はなくなりました。つまり、クエリ列はインデックス列と一致しています

インデックスをカバーすることで、IO を効果的に削減し、クエリの効率を向上させることができます。

使い物にならない。

Select *

次のテーブルには 5,000 万のテスト データがあり、そのうちの 1 つはselect *インデックス フィールドを使用しています。クエリ時間の比較では、n の差があります。これがインデックスをカバーする利点です。同時に、使用を避けるようにしてくださいSelect *

[外部リンクの画像の転送に失敗しました。ソース サイトにリーチング防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-gP1pu13z-1659795260688) (/Users/xujiangtao/Desktop/screenshot 2022-08-06 21.23.23.png) ]

ここに画像の説明を挿入

インデックス障害のシナリオ

  1. ジョイント インデックスが左端の一致原理を満たしていません
  2. 使用select *
  3. インデックス列は関数計算に参加します
  4. 123%この種の他のあいまいなクエリに加えて。%123%123%失敗します
  5. 型の暗黙的な変換
  6. インデックス列を比較する
  7. 使用条件がない、存在しない、null でない

おすすめ

転載: blog.csdn.net/languageStudent/article/details/126202147