...

データベースの照合順序がパフォーマンスに影響を与える理由

データベースの照合順序 MySQL が文字列を比較およびソートする方法を制御します。これらは CPU 負荷、インデックスの使用、および I/O に直接影響します。遅い照合順序を選択したり、設定を混在させたりすると、クエリが長くなり、変換が発生し、「Illegal mix」エラーが発生する危険性があります。.

中心点

  • 文字セット/照合順序: 誤った組み合わせは変換を強制し、速度を低下させます。.
  • インデックス: 大文字と小文字を区別しない設定は選択性を低下させ、大文字と小文字を区別する設定は一致の速度を向上させます。.
  • Unicode: utf8mb4 はより正確ですが、CPU をより多く消費します。.
  • 一貫性: 統一設定により、ファイルソートおよびフルスキャンは実行されません。.
  • チューニング: メモリ、プーリング、クエリ設計と照合選択を組み合わせる。.

コレーションとは何か、そしてそれがパフォーマンスに与える影響について

私はこうしている。 コラージュ, 文字列の比較およびソートルールを定義するために使用します。これらは データベースの文字セット 文字エンコーディングを決定する、utf8mb4 や latin1 などの照合順序を組み合わせます。utf8mb4_unicode_ci のようなより正確な Unicode 照合順序を選択すると、比較ごとの計算コストが増加します。 MySQL 8.0 での測定では、新しい Unicode 照合順序を使用すると、OLTP ワークロードの速度は 10~16 % 低下しましたが、その代わりに、言語や絵文字の比較の精度が向上しました(出典 [2])。純粋な速度ワークロードでは、utf8_general_ci などの単純なルールが有効ですが、その結果の精度は低くなります(出典 [2])。.

文字セットと照合順序:小さな違い、大きな影響

文字セット MySQL がバイトを保存する方法を決定し、照合順序は MySQL がこれらのバイトを比較する方法を決定します。JOIN や WHERE 条件で照合順序を混在させると、MySQL はオンザフライで変換を行います。これは、大きなテーブルでは明らかに負荷が高くなります(出典 [2])。これは CPU を消費し、一時テーブルを生成し、ディスク上のファイルソートにつながる可能性があります。 そのため、アプリレベル、データベース、テーブル、列は厳密に統一しています。より広範な最適化のために、照合順序の問題も私の対策に含めています。 SQLデータベースの最適化 にある。

バージョンとデフォルト:5.7 から 8.0 への変更点

アップグレードの際には、次の点に注意しています。 デフォルト: MySQL 8.0 はデフォルトで utf8mb4 そして多くのビルドで utf8mb4_0900_ai_ci. 古いインストールでは、多くの場合 ラテン1スウェーデン語CI 或いは utf8_general_ci. この変更は、エンコーディングだけでなく、ソート順や等価性ルールも変更します。その結果、 ORDER BY-結果が異なる場合, ユニーク-インデックスが新たに衝突したり、以前は「同じ」だったものが突然重複したり(またはその逆)する場合があります。そのため、アップグレードは事前に確認して計画しています。 SELECT @@character_set_server, @@collation_server, @@collation_database; そして、ターゲットシステムで意図的にデフォルトを設定します。同時に、 utf8mb4_0900_ai_ci 対して utf8mb4_unicode_ci 私の実際のクエリでは、0900 バリエーション(ICU ベース)はより正確であるが、より高価なルールを伴うことが多い(出典 [2])ため、このようになっています。.

インデックスとクエリプラン:照合順序が速度を低下させる場合

照合は、 インデックスの利用 大文字小文字を区別しない (_ci) は検索範囲を広げますが、選択性を低下させます。これにより、オプティマイザーがインデックスを使用する頻度が減少します。大文字小文字を区別する (_cs) は完全一致の検索を高速化しますが、すべての要件に適しているわけではありません。 列の照合順序が変更されると、比較ルールが変更され、プランも変更されます。ファイルソートがより頻繁に使用されるようになり、一部は一時テーブルも使用されます(出典 [1]、[3])。インデックスの効果に関する詳細については、「„インデックス:メリットとリスク“ を削除。.

よくあるエラーと直接的な解決策

その報告 違法ミックス ほとんどの場合、混合照合順序を示しています。私は、クエリで COLLATE を使用して短期的にこの問題を解決し、長期的には列を統一します。ファイルソートと高いレイテンシが発生した場合、ORDER BY 列を確認し、照合順序をインデックス定義に適合させます(出典 [3])。 TEXT/VARCHAR 列を含む JOIN では、照合順序が同一であることを確認します。そうしないと、変換によってオプティマイザーが非効率的なプランを強制してしまうからです。一貫性を確保することで、多くの場合、ミリ秒単位の測定可能なパフォーマンスの向上が即座にもたらされます。.

MySQLの階層構造:サーバーから表現まで

MySQL は、以下の照合順序を認識しています。 5つのレベル: サーバー、データベース、テーブル、列、式。最下位レベルが優先されるため、差異があると予期せぬ結果になります。私は `SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA`、`SHOW TABLE STATUS`、`SHOW FULL COLUMNS` を使用して設定を確認しています。 クエリ `col1 COLLATE utf8mb4_unicode_ci = col2` に該当する場合、異なる列の照合順序が比較を評価するため、時間がかかります(出典 [1])。変更を行う前に、バックアップを作成し、ステージングで再エンコードをテストして、データの歪みを防ぎます。.

接続およびセッション設定:バグが発生する場所

多くの問題は、計画通りではなく、 セッション. 。変数をチェックします。 character_set_client, character_set_connection, character_set_results そして collation_connection. ORM は一部 セット名 これによりサーバーのデフォルト設定が上書きされます。混合デプロイメントは「見えない」変換につながります。私は明確なルールに従っています。アプリは UTF-8 (utf8mb4) を送信し、接続は SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; または、ドライバオプションで設定します。デバッグには、 SHOW VARIABLES LIKE 'collation%'; そして SELECT COLLATION(column), COERCIBILITY(column) それぞれ COLLATION('リテラル'). ここで値が異なる場合、一時テーブルやミスマッチエラーの原因はたいていすぐに見つかります(出典 [1])。.

大文字と小文字を区別しない vs. 大文字と小文字を区別する:どちらの選択が適切か

と一緒に _ci 大文字と小文字を区別しないため、使いやすさが向上します。その代わりに、選択性が低下し、LIKE 検索がインデックスに正しくアクセスする頻度が減少します。 _cs 正確な比較を行い、より迅速にポイント照会を行いますが、利便性は失われます。ログイン、トークン、ID には _cs を、検索フィールドには多くの場合 _ci を使用します。悪用や変換を防ぐため、両者を明確に区別しています。.

細かい点:アクセント、幅、バイナリルール(_ai、_as、_bin)

私は大文字と小文字の区別以上のものを区別しています。. _ai (アクセント区別なし) は「é」と「e」を同じものとして扱います。; _as (アクセントに敏感) がそれらを区別します。東アジア言語では、さらに ロール(フル幅/ハーフ幅) _bin 純粋なバイト比較を実行します。これは最速ですが、言語的な論理は使用しません。ログ、ハッシュ、ID については、私は _bin 或いは _cs, 、ユーザー検索で頻繁に _ai, タイプミスやアクセントが問題にならないように。私は意図的に例をテストしています。 SELECT 'straße' = 'strasse' COLLATE utf8mb4_0900_ai_ci; 用品 TRUE, 、一方で ... COLLATE utf8mb4_0900_as_cs; FALSE です。このようなルールによって、インデックス範囲スキャンに含まれる行数が決定され、その結果、レイテンシと I/O が決定されます。.

ベンチマークを正しく読む:精度にはCPUのコストがかかる

Unicode 照合順序(例: utf8mb4_unicode_ci また、utf8mb4_0900_ai_ci は言語、発音区別符号、絵文字を正しくカバーします。比較ロジックはより複雑であるため、比較ごとに CPU 負荷が高くなります。 多くの文字列比較を行う OLTP シナリオでは、ワークロードやデータセットのサイズに応じて、10~16 % の実行時間増加が見られます(出典 [2])。小さなテーブルではその影響はそれほど大きくありませんが、広範囲の検索やソートではより大きな影響があります。私は、ユースケースごとに、ユーザーの要件を考慮して決定します。.

インデックスサイズ、プレフィックス制限、およびメモリ要件

と一緒に utf8mb4 インデックスの幅は、1文字が最大4バイトを占める可能性があるため、慎重に計画しています。InnoDB はインデックスキーの長さを制限しています(従来は767バイト、新しいバージョンおよび行形式では実質的に3072バイトまで)。これは VARCHAR-列、複合インデックス、およびカバリングインデックスを無効にします。 そこで、191 文字 (191×4≈764 バイト) で E メールや URL を表現できるかどうかを検証します。5.7 の設定では、これは多くの場合、確実な選択でした。8.0 では、複合インデックスが範囲外にならない限り、多くの場合 255 まで上げることができます。必要な場合は、 プレフィックスインデックス: CREATE INDEX idx_email ON users(email(191)); これによりスペースは節約できますが、選択性は低下します。私はその効果を EXPLAIN ANALYZE およびスロークエリログ(出典 [3])です。また、キーが大きくなるとバッファプールが肥大化します。バイトが 1 バイト増えるごとに、キャッシュの負荷と I/O が増加するため、照合の決定はメモリコストに影響を与えます。.

ホスティングのチューニング:照合順序、バッファ、プーリングを一緒に考える

私は innodb_buffer_pool_size, インデックスとホットデータがメモリに残るようにします。コネクションプーリングにより、リクエストごとのオーバーヘッドを削減し、プロキシレイヤーによりスパイクを低減します。ファイル形式、リドゥログサイズ、ページサイズについては、ターゲットワークロードに合わせて調整します。さらに、ストレージエンジンも慎重に選択します。 InnoDB 対 MyISAM トランザクション、ロック、クラッシュの安全性における典型的な違いを示しています。一貫性のある照合順序がなければ、このチューニングの一部は無駄になってしまいます。.

ベストプラクティス:使用シナリオによる選択

最新のウェブアプリには、私は utf8mb4 文字セットとして、絵文字と完全な Unicode カバレッジを提供するため。複数の言語でのソートに最高の精度が必要な場合は、utf8mb4_unicode_ci または utf8mb4_0900_ai_ci を使用します。 単純な比較での純粋な速度に関しては、utf8_general_ci の方が多くの場合高速ですが、不正確さが許容されます(出典 [2])。私は、サーバー、スキーマ、テーブル、および列レベルで照合戦略の一貫性を保っています。EXPLAIN ANALYZE およびスロークエリログによるテストにより、この決定が確実なものとなっています(出典 [3])。.

照合 精度 スピード 絵文字のサポート こんな人に向いている
utf8_general_ci 低い 高い いいえ クイック検索
utf8_unicode_ci 高い ミディアム いいえ Unicodeアプリ
utf8mb4_unicode_ci 非常に高い 低い モダンウェブ
utf8mb4_0900_ai_ci 最高 ミディアム 多言語

ステップバイステップ:ダウンタイムのない移行

私は次のように始める。 インベントリー:どのスキーマ、テーブル、列がどの照合順序を使用しているかを調べます。その後、データをバックアップし、重要なテーブルをエクスポートし、ステージングにリハーサルを作成します。変更は、`ALTER TABLE … CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;` を使用して、使用頻度の低いテーブルから開始します。 大きなテーブルについては、メンテナンスウィンドウを計画するか、Percona Toolkit(出典 [1]、[2])などのオンライン移行ツールを使用します。移行後、EXPLAIN、スロークエリログを確認し、レイテンシを比較します。.

診断:データベースへの適切な質問

私はチェックする 図式 および `SHOW FULL COLUMNS` を使用して、差異を可視化します。ファイルソートや一時テーブルが発生した場合、sort_buffer_size を盲目的に増やすのではなく、照合順序の不一致を解消します。 EXPLAIN を使用して、インデックスが機能しているかどうか、またはフルスキャンが行われているかどうかを確認します。パフォーマンススキーマを使用して、tmp_disk_tables および sort_merge_passes を測定し、ソートに関連する I/O を検出します。これにより、文字列の比較に直接起因するボトルネックを見つけることができます(出典 [3])。.

GROUP BY、DISTINCT、UNIQUE:照合順序のセマンティックな結果

照合は、値が「等しい」とみなされる場合を定義します。これは、 重複排除 そして 一意性ルール. 私は _cs に於いて _ci または _as に於いて _ai, 、 ユニーク-インデックスが突然衝突を報告する。移行前に、潜在的な競合を探します。 SELECT col, COUNT(*) FROM t GROUP BY col COLLATE utf8mb4_0900_ai_ci HAVING COUNT(*) > 1;. 。そうすることで、ターゲットの照合で一致する行を確認できます。これは、 GROUP BY そして DISTINCTグループ数はルールセットによって決まるから、計画もそれに応じて変わる(ソートやハッシュの負荷が多少変わる)。レポートテーブルの場合は、グループ数が少なくなるようわざと「大まかな」照合を使うのがいいかも。でも、レジIDやログインの場合は、それだとリスクがあるよ。.

デザインパターン:バイナリ、生成列、機能インデックス

私は別 代表 そして 検索: 表示される列は「美しい」照合順序(例:. utf8mb4_0900_ai_ci)、それに加えて私は 生成された列 パフォーマンスの高い比較のために正規化されたもの(小文字、バイナリなど)を使用します。例: ALTER TABLE user ADD name_search VARCHAR(255) GENERATED ALWAYS AS (LOWER(name)) STORED, ADD INDEX idx_name_search (name_search); を使って _bin- または _cs-照合 name_search 私は正確で迅速なマッチングを得ることができます。 WHERE name_search = LOWER(?). MySQL 8.0 では、さらに インデックスの照合 指定する: CREATE INDEX idx_name_ai ON user (name COLLATE utf8mb4_0900_ai_ci); たとえば、列はそのまま残ります。. _cs, 、インデックスは意図的に _ai フルスキャンを行わない「ファジー」検索に便利です。アプリのクエリジェネレータが正しい列またはインデックスを使用するように、このパターンをスキーマに記述しています。.

LIKE、接頭辞、全文検索:実際に高速化をもたらすもの

時点では ライク-検索には通常の照合規則が適用されます。先頭のワイルドカード (LIKE 'c')は、照合順序がどれほど適切に選択されているかに関係なく、インデックスの使用を妨げます。そのため、私は検索パターンを、プレフィックスが使用されるように再構成しています(LIKE 'abc%')を使用し、MySQL が途中で変換を行わないよう、照合順序の互換性に注意してください。大きな自由テキストについては、私は フルテキスト-インデックス。トークン化は、ほとんどの場合、照合とは無関係ですが、文字エンコーディングと正規化はヒットに影響を与えます。CJK 環境では、NGRAM パーサーが役立ちます。西洋言語では、ステミング/ストップワードがあまりにも多くの結果を返さないように、「粗い」照合は避けています。ここでも、フィールドから接続までの一貫性を保つことで、一時テーブルやファイルソートを回避できます(出典 [3])。.

実践:WordPress、ショップ、API を高速に保つ

コンテンツおよびショップシステムは、以下の点でメリットがあります。 utf8mb4_unicode_ci, スラグ、カテゴリ、ユーザーコンテンツをきちんとソートするから。 プラグインが異なる照合順序を作成しないように注意しています。API および認証パスでは、インデックスによる完全一致を保証するために、トークンに _cs を設定しています。大きなテキストフィールドで ORDER BY を使用したレポートでは、照合順序の一貫性と適切なカバリングインデックスを組み合わせています。さらに、スループットを向上させるためのヒントも参照しています。 SQLデータベースの最適化 で。

コンパクトな概要

私が選ぶ コラージュ 意識的:速度、正確性、ユーザーの期待が判断を決定します。統一された設定は、変換、ファイルソート、非効率的な計画を防ぎます。Unicode バリエーションはより良い結果をもたらしますが、CPU をより多く消費します。MySQL 8.0 での測定では、集中的な文字列ワークロードで 10~16 % の損失が見られます(出典 [2])。 クリーンなスキーマ設計、インデックス、バッファプール、プーリングにより、MySQL インスタンスは確実にスケーリングします。体系的なチェック、テスト、統合を行うことで、レイテンシを削減し、MySQL の照合パフォーマンスを大幅に向上させることができます。.

現在の記事

TCP 輻輳制御の視覚化機能を備えたネットワークサーバー
技術情報

TCP 輻輳制御アルゴリズム:影響の比較

BBR や CUBIC などの TCP 輻輳制御アルゴリズムは、ネットワークパフォーマンスに大きな影響を与えます。ホスティングに関する比較とヒントをご紹介します。.