簡単な答えは「はい」です。主キーには順序があり、すべてのインデックスには順序があり、主キーは単に一意のインデックスです。
あなたが正しく言ったように、あなたはデータが保存された順序で返されるデータに頼るべきではありません、オプティマイザーは好きな順序でそれを自由に返すことができます、そしてこれはクエリプランに依存します。ただし、クエリが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)を使用してそれで完了します。クエリオプティマイザーの内部動作を調べて、クエリプラン内のクラスター化されたインデックスのさまざまな順序を観察するために、どのような種類の断片化やデータ範囲が必要になるかを調べようとしても、あまり眠りにつくことはありません。