sql >> データベース >  >> RDS >> Mysql

MySQLの主キーはすでにある種のデフォルトの順序になっていますか

    簡単な答えは「はい」です。主キーには順序があり、すべてのインデックスには順序があり、主キーは単に一意のインデックスです。

    あなたが正しく言ったように、あなたはデータが保存された順序で返されるデータに頼るべきではありません、オプティマイザーは好きな順序でそれを自由に返すことができます、そしてこれはクエリプランに依存します。ただし、クエリが12年間機能した理由を説明しようと思います。

    クラスター化されたインデックスは単なるテーブルデータであり、クラスター化キーはデータが格納される順序を定義します。データはリーフに格納され、クラスタリングキーはルート(および中間ノート)がポインターとして機能して、データを取得するための右リーフ。非クラスター化インデックスは非常によく似た構造ですが、最下位レベルには、クラスター化インデックスのリーフ上の正しい位置へのポインターが含まれているだけです。

    MySQLでは、主キーとクラスター化インデックスは同義であるため、主キーは順序付けられていますが、基本的に2つの異なるものです。他のDBMSでは、主キーとクラスター化インデックスの両方を定義できます。これを行うと、主キーは、クラスター化インデックスへのポインターを持つ一意の非クラスター化インデックスになります。

    最も簡単な用語では、主キーであるID列と、別の列(A)を持つテーブルを想像できます。クラスター化インデックスのBツリー構造は次のようになります。

    Root Node
                                    +---+
                                    | 1 |
                                    +---+
    Intermediate Nodes
    
                        +---+       +---+       +---+
                        | 1 |       | 4 |       | 7 |
                        +---+       +---+       +---+
    
    Leaf
                +-----------+   +-----------+   +-----------+
        ID ->   | 1 | 2 | 3 |   | 4 | 5 | 6 |   | 7 | 8 | 9 |
        A ->    | A | B | C |   | D | E | F |   | G | H | I |
                +-----------+   +-----------+   +-----------+
    

    実際には、リーフページははるかに大きくなりますが、これは単なるデモです。各ページには、ツリーを簡単に移動できるように、次のページと前のページへのポインタもあります。したがって、次のようなクエリを実行すると、次のようになります。

    SELECT ID, A
    FROM T
    WHERE ID > 5
    LIMIT 1;
    

    一意のインデックスをスキャンしているため、これはシーケンシャルスキャンである可能性が非常に高くなります。ただし、保証されていない可能性が非常に高いです。

    MySQLはルートノードをスキャンします。一致する可能性がある場合は、句がWHERE ID < 0のようなものであれば、中間ノードに移動します。 そうすれば、MySQLは、ルートノード以外に行かなければ結果がないことを認識します。

    中間ノードに移動すると、ID > 5の検索を開始するために、2番目のページ(4〜7)から開始する必要があることを識別できます。 。したがって、LIMIT 1をすでに識別している状態で、2番目のリーフページから順番にリーフをスキャンします。 一致するもの(この場合は6)が見つかると停止し、リーフからこのデータを返します。このような単純な例では、この動作は信頼性が高く論理的であるように見えます。リーフページの最後にあるID値を選択して例外を強制しようとしましたが、リーフが逆の順序でスキャンされるかどうかを確認しましたが、まだこの動作を生成できていないため、これは意味しません。それは起こらないか、MySQLの将来のリリースは私がテストしたシナリオではこれを行いません。

    要するに、注文を追加するか、MIN(ID)を使用してそれで完了します。クエリオプティマイザーの内部動作を調べて、クエリプラン内のクラスター化されたインデックスのさまざまな順序を観察するために、どのような種類の断片化やデータ範囲が必要になるかを調べようとしても、あまり眠りにつくことはありません。



    1. search_pathに関してデフォルト値の式関数はいつ/どのようにバインドされますか?

    2. MySQLデータベーステーブル列にPyQt5を含む画像ファイルを挿入する

    3. STDINからPostgresqlに行をインポートするにはどうすればよいですか?

    4. Oracleで週ごとのデータを取得する方法