답변:
SQL Server에 대한 비슷한 질문에 대한 답변 을 다시 게시하십시오 .
SQL 세계에서 순서는 데이터 집합의 고유 속성이 아닙니다. 따라서 ORDER BY 절을 사용하여 데이터를 쿼리하지 않는 한 RDBMS에서 데이터가 특정 순서로 또는 심지어 일관된 순서로 다시 올 것이라는 보장은 없습니다.
따라서 귀하의 질문에 대답하십시오 :
ORDER BY
. 다른 일을하는 것은 반갑지 않은 놀라움에 대비하는 것입니다.이것은 MySQL뿐만 아니라 모든 SQL의 속성입니다. SQL-92 스펙 의 관련 텍스트 는 다음과 같습니다.
<order by clause>가 지정되지 않은 경우 Q 행의 순서는 구현에 따라 다릅니다.
커서 스펙에 유사한 텍스트 비트가 있습니다.
ORDER BY
절이 없는 행의 순서는 다음과 같습니다.
삽입은 순서가 맞지 않고 혼란 스럽습니다. 작성된 색인은 요소가 색인 인 링크 된 목록에서 적절한 위치에 삽입되는 순서를 갖습니다. 하나의 인덱스 요소에서 다음 인덱스 요소로의 순방향 이동 링크, 순회 및 무결성 목적을위한 역방향 링크 및 테이블의 실제 레코드에 대한 포인터 세트가있는 인덱스에 대한 3 중 링크리스트를 생각해보십시오. 해당 색인 요소와 일치합니다.
스토리지에 혼란스러운 실제 데이터. 보관 및 시공에서 주문한 데이터와 관련된 색인. 정렬되거나 정렬되지 않은 실제 데이터 풀은 관련된 쿼리에 따라 다릅니다.
MEMORY 스토리지 엔진에 관해서 는 기본 인덱스 레이아웃 HASH
대신 BTREE
인덱스 레이아웃의 측면이 사용되지 않기 때문에 순서가 삽입 순서대로 될 것으로 예상합니다 . k를 인덱싱하고 k는 동일한 값이므로 모든 키가 동일한 해시 버킷에 입력 됩니다. 해시 버킷을 채우는 데 추가 복잡성을 가정 할 이유가 없으므로 삽입 순서가 가장 적합합니다.
나는 동일한 샘플 테이블과 데이터를 가져 와서 30 INSERT
초 동안 실행 했으며 이것을 얻었습니다.
mysql> use test
Database changed
mysql> drop table if exists t;
Query OK, 0 rows affected (0.00 sec)
mysql> create table t(k int, v int,index k(k)) engine=memory;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t values
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3);
Query OK, 30 rows affected (0.00 sec)
Records: 30 Duplicates: 0 Warnings: 0
mysql> select * from t;
+------+------+
| k | v |
+------+------+
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
+------+------+
30 rows in set (0.00 sec)
mysql>
k : 10 및 11에 대해 두 가지 다른 값을 추가하는 것을 테스트하기로 결정했습니다.
mysql> use test
Database changed
mysql> drop table if exists t;
Query OK, 0 rows affected (0.02 sec)
mysql> create table t(k int, v int,index k(k)) engine=memory;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t values
-> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
-> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3);
Query OK, 30 rows affected (0.00 sec)
Records: 30 Duplicates: 0 Warnings: 0
mysql> select * from t;
+------+------+
| k | v |
+------+------+
| 11 | 1 |
| 11 | 2 |
| 11 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 11 | 1 |
| 11 | 2 |
| 11 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
+------+------+
30 rows in set (0.00 sec)
mysql>
삽입 순서처럼 보입니다. k = 11은 10보다 먼저 해시 된 첫 번째 키입니다. 11 대신 10을 먼저 삽입하는 것은 어떻습니까? 이것이 내가 얻은 것입니다 :
mysql> use test
Database changed
mysql> drop table if exists t;
Query OK, 0 rows affected (0.02 sec)
mysql> create table t(k int, v int,index k(k)) engine=memory;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t values
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
-> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3);
Query OK, 30 rows affected (0.00 sec)
Records: 30 Duplicates: 0 Warnings: 0
mysql> select * from t;
+------+------+
| k | v |
+------+------+
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 11 | 1 |
| 11 | 2 |
| 11 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 11 | 1 |
| 11 | 2 |
| 11 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
+------+------+
30 rows in set (0.00 sec)
mysql>
만장일치입니다 !!! 삽입 순서가 정답입니다.
MEMORY 스토리지 엔진의 인덱스 사용에 대한 참고 사항
MEMORY에 대한 범위 검색은 비슷한 성능을 발휘합니다.
색인을 작성할 때 색인 USING BTREE
정의와 함께 절을 지정할 수 있습니다 . 이것은 범위 쿼리를 개선합니다.
특정 행을 검색하면 HASH
또는의 성능이 동일한 결과가 나타납니다 BTREE
.
업데이트 2011-09-22 11:18 EDT
나는 오늘 흥미로운 것을 배웠다. Percona의 @Laurynas Biveinis 가 제공하는 링크를 읽었습니다 . Percona 링크는 MySQL 5.5.15의 MEMORY 테이블에 대해 알려줍니다 .
행 순서
ORDER BY가 없으면 레코드가 이전 MEMORY 구현과 다른 순서로 리턴 될 수 있습니다. 이것은 버그가 아닙니다. ORDER BY 절이없는 특정 주문에 의존하는 응용 프로그램은 예기치 않은 결과를 제공 할 수 있습니다. ORDER BY가없는 특정 순서는 스토리지 엔진 및 쿼리 옵티 마이저 구현의 부작용으로 마이너 MySQL 릴리스간에 변경 될 수 있습니다.
이것은 오늘 볼 수있는 좋은 링크였습니다. 내가 준 대답은 내가로드 한 테이블이 MySQL 5.5.12에서 오늘 예상되는 순서로 검색되었음을 보여줍니다. Percona와 @Laurynas Biveinis가 지적 했듯이 , 다른 부 릴리스에서는 보장되지 않습니다.
따라서 내 답변을 방어하기보다는 @Laurynas Biveinis 의 답변을 가장 최신 정보이기 때문에 홍보하고 싶습니다 . @Laurynas Biveinis를 위한 Kudos와 모자 떨어져 . 또한 질문에 대한 버전 별 답변을 홍보하지 않기로 정중하게 @eevar 에게 감사의 말씀 을 전합니다. 그들은 둘 다 오늘 내 공감대를 얻는다.