「並べ替え」という言葉を考えると、ほとんどのアプリに並べ替え場所があるという第一印象があります。Taobaoの商品は購入時間順に並べ替えられ、Bilibiliのコメントは人気順に並べ替えられます... MySQL でのソートに関して、最初に思い浮かぶことは何でしょうか?キーワードの順序は?順序フィールドにインデックスを設定するのが最適ですか?リーフノードはすでに整っていますか?それとも、MySQL 内でのソートはできるだけ避けるべきでしょうか? 事件の原因ここで、ユーザーの友人テーブルがあるとします。 テーブル `user` を作成します ( `id` int(10) AUTO_INCREMENT, `user_id` int(10)、 `friend_addr` varchar(1000)、 `friend_name` varchar(100)、 主キー (`id`)、 キー `user_id` (`user_id`) )ENGINE=InnoDB; 現在、表には注意が必要な点が 2 つあります。
ある日、Xiaoyuan というジュニア開発エンジニアが、Xiaowang というジュニアプロダクトマネージャーから次のようなリクエストを受けました。 そこで、Xiaoyuan は次の SQL を記述しました。 user_id=? の user から friend_name,friend_addr を選択します。名前で並べ替えます。 あっという間に、Xiaoyuan は大々的な宣伝とともにオンラインになりました。すべて順調に進んでいたのですが、ある日、オペレーションのクラスメートが次のような質問をしました。 user_id=10086 の user から friend_name,friend_addr を選択し、名前で並び替えます しかし、このクエリは通常よりもはるかに遅く、データベースは遅いクエリを報告しました。Xiaoyuan はパニックになりました。何が起こっているのですか? user_id にはインデックスがあり、select * の代わりに select friend_name, friend_addr のみを巧みに使用しました。この時、シャオユアンは自分を慰め続け、落ち着くように自分に言い聞かせていましたが、突然、explain コマンドがあることを思い出しました。彼は、explain を使用してその SQL の実行プランを確認することにしました。シャオユアンが explain を使用した後、彼は追加フィールドに危険そうな単語「using filesort」を見つけました。 「このクエリは実際には伝説的なファイルソートを使用していますが、友達があまりいない人の場合は、ファイルソートを使用しても高速になるはずです」と、user_id=10086に多くの友達がいない限り。その後、Xiaoyuanが確認したところ、このユーザーには実際には10万人以上の友達がいることがわかりました〜。 小さな猿は考え込んでいました。どうやら、この責任は私にあるようです。100,000 のデータ ポイントは多すぎます。また、filesort を使用したソートの原理とは何でしょうか? 解剖学ファイルの並べ替え上記の問題は、10w のデータが大きすぎて、ソートされていなくても遅くなるということだと言う人がいるかもしれません。これは実際には理にかなっています。10w のデータを一度にチェックすると、MySQL メモリ バッファとネットワーク帯域幅の両方が非常に消費されます。1000 の制限を追加したらどうなるでしょうか。全体的なデータ パケット サイズが小さくなったため、ネットワーク帯域幅の問題は確実に解決されましたが、filesort の使用に関する問題は解決されていません。これを見ると、filesort を使用するとファイルがソートされるのかという疑問が湧くかもしれません。ファイル内ではどのように分類されますか?あるいは、こう尋ねてみましょう。ソートを設計するように依頼された場合、どのように対処しますか?これらの質問と考察を踏まえて、filesort の使用に伴う技術的な困難とその解決方法を見てみましょう。
すべてがスムーズに見えますが、sort_buffer はメモリ領域を占有するため、扱いにくいです。メモリ自体は無限ではなく、上限が確実にあります。もちろん、sort_buffer が小さすぎることはできません。小さすぎると、あまり意味がありません。 InnoDB ストレージ エンジンでは、この値はデフォルトで 256K になります。 mysql> 'sort_buffer_size' のような変数を表示します。 +------------------+--------+ | 変数名 | 値 | +------------------+--------+ | ソートバッファサイズ | 262144 | +------------------+--------+ つまり、sort_buffer に入れるデータが 256K より大きい場合、sort_buffer のクイック ソート メソッドは確実に機能しません。この時点で、MySQL はデータ サイズに応じて自動的に拡張できないのかと疑問に思うかもしれません。さて、MySQLはマルチスレッドモデルです。各スレッドが拡張されると、他の機能に割り当てられるバッファ(変更バッファなど)が小さくなり、他の機能の品質に影響を与えます。 このとき、ソート方法を変更する必要があります。はい、これは実際のファイル ソート、つまりディスク上の一時ファイルです。MySQL はマージ ソートの概念を使用して、ソートするデータをいくつかの部分に分割します。各データはメモリ内でソートされた後、一時ファイルに格納されます。最後に、これらのソートされた一時ファイルのデータはマージされ、再度ソートされます。これは典型的な分割統治の原則です。具体的な手順は次のとおりです。
ファイルのソートが非常に遅いのですが、他に解決策はありますか?上記のソート処理を通じて、ソートするデータが非常に大きく、sort_buffer のサイズを超える場合は、ファイル ソートが必要であることがわかります。ファイル ソートにはバッチ ソートとマージが含まれ、非常に時間がかかります。この問題の根本的な原因は、sort_buffer が十分ではないことです。friend_name をソートする必要があることに気付いたかどうかはわかりませんが、friend_addr も sort_buffer に詰め込まれています。このように、1 行のデータのサイズは friend_name の長さ + friend_addr の長さに等しくなります。sort_buffer に friend_name フィールドのみを保存できますか? この方法では、全体的な使用スペースが大きくなり、一時ファイルが不要になる可能性があります。そうです、これは次に説明するもう 1 つのソート最適化、rowid ソートです。 rowidソートの考え方は、不要なデータをsort_bufferから除外し、必要なデータのみをsort_bufferに保持することです。では、必要なデータとは何だと思いますか? friend_name を入力するだけですか?これは絶対にうまくいきません。ソートが完了したら、friend_addr はどうなるのでしょうか?したがって、主キー ID も入力する必要があります。ソート後、ID を介してセカンダリ テーブルに戻り、friend_addr を取得できます。したがって、一般的なプロセスは次のようになります。
実際にここで注意すべき点がいくつかあります。
そこで疑問になるのが、MySQL は 2 つの方法のどちらを選択すべきかということです。どちらの方法を使用するかは、特定の条件によって決まります。条件は、sort_buffer 内の単一行の長さです。長さが大きすぎる場合 (friend_name + friend_addr の長さ)、rowid が使用されます。それ以外の場合、最初の方法では、max_length_for_sort_data に基づく長さの標準が使用されます。これは、デフォルトで 1024 バイトです。 mysql> 'max_length_for_sort_data' のような変数を表示します。 +--------------------------+-------+ | 変数名 | 値 | +--------------------------+-------+ | ソートデータの最大長 | 1024 | +--------------------------+-------+ テーブルに戻って再度並べ替えたくない実際、上記のどの方法を使用する場合でも、すべてテーブルに戻って並べ替える必要があります。テーブルに戻るのは、セカンダリ インデックスにターゲット フィールドがないためであり、並べ替えるのは、データが順序付けられていないためです。セカンダリ インデックスにターゲット フィールドがあり、すでに並べ替えられている場合は、両方の長所を兼ね備えた方法ではないでしょうか。 そうです、それはジョイントインデックスです。(user_id、friend_name、friend_addr)のジョイントインデックスを作成するだけです。このように、このインデックスを介してターゲットデータを取得でき、friend_nameフィールドはすでにソートされています。friend_addrフィールドもあります。テーブルに戻ったり、再度ソートしたりすることなく、1回で完了します。したがって、上記の SQL の場合、一般的なプロセスは次のようになります。
共同インデックスはこの問題を解決できますが、実際のアプリケーションでは盲目的に構築すべきではありません。実際のビジネス ロジックに基づいて構築する必要があるかどうかを判断する必要があります。類似のクエリが頻繁に発生しない場合は、共同インデックスによってストレージ スペースとメンテナンス コストが増加するため、構築する必要はありません。 要約する
上記はMySQLデータベースの並べ替えの詳細な内容です。MySQLデータベースの並べ替えの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
>>: 1 行のコードでさまざまな IE 互換性の問題を解決します (IE6-IE10)
理由は分かりませんが、UIではハニカム効果(手を広げたような効果)のデザインが好まれます。 1. 六...
序文以前、画像とテキストの垂直方向のずれの問題について説明しました。ここで示した小さな例では、小さな...
1. MacにMySQLデータベースをインストールする1. MySQLデータベースをダウンロードする...
MySQL ユーザーと権限MySQL には、MySQL と呼ばれるシステムに付属するデータベースがあ...
目次1. 解凍する2. データフォルダを作成する3. MySQLに環境変数を追加する3.1 コントロ...
方法1: var a = [1,2,3]; var b = [4,5] b を連結します。 コンソー...
mysql-8.0.12-winx64 解凍版のインストールを記録して、みんなで共有しました。 1....
目次1. オブジェクトをマップとして扱わない1. 未定義のプロパティはプロトタイプチェーンを通じてア...
序文この記事は、最も人気のある言語で最も退屈な基礎知識を説明することを目的としていますこのトピックは...
場合によっては、ベースイメージに特定の依存関係をインストールする必要があります。Dockerfile...
HTML を使用してコンテンツをマークアップする目的は、Web ページにセマンティクスを与えることで...
目次1. はじめに2. 使用方法3. 開発プロセス1. モデル例2. イベントとアニメーション4. ...
質問まず、私が遭遇した問題についてお話しします。まず、そういった需要があるわけです。フロントエンドは...
1.コンテナに入った後 /etc/hosts を cat するコンテナ自体の IP アドレスと (-...
DOSBox を使用すると、Windows で DOS をシミュレートし、楽しい作業を行うことができ...