創建一個表格,一個是主鍵列,一個是索引列。然後插入一批數據,調用select * from test_b,可以發現輸出結果並沒有按照Id有序,而是按照Type有序。
如果希望按照Id有序,可以使用force index (primary)這一hint語句。
mysql> CREATE TABLE `test_b` (
-> `Id` int(11) NOT NULL,
-> `Type` int(11) DEFAULT NULL,
-> PRIMARY KEY (`Id`),
-> KEY `IDX_Type` (`Type`)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.20 sec)
mysql> insert into test_b values(1,1),(2,6),(3,2),(7,3),(4,1);
Query OK, 5 rows affected (0.09 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from test_b;
+----+------+
| Id | Type |
+----+------+
| 1 | 1 |
| 4 | 1 |
| 3 | 2 |
| 7 | 3 |
| 2 | 6 |
+----+------+
5 rows in set (0.03 sec)
mysql> select * from test_b force index (primary);
+----+------+
| Id | Type |
+----+------+
| 1 | 1 |
| 2 | 6 |
| 3 | 2 |
| 4 | 1 |
| 7 | 3 |
+----+------+
5 rows in set (0.00 sec)
觀察select * from test_b的前兩條結果:(1,1),(4,1),當Type相等的時候,按照Id排序。為了確認這一點,再多插入點數據觀察,結論相同。
mysql> insert into test_b values(9,3),(6,3),(10,3);
Query OK, 3 rows affected (0.04 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from test_b ;
+----+------+
| Id | Type |
+----+------+
| 1 | 1 |
| 4 | 1 |
| 3 | 2 |
| 6 | 3 |
| 7 | 3 |
| 9 | 3 |
| 10 | 3 |
| 2 | 6 |
+----+------+
8 rows in set (0.00 sec)
默認情況下為什麼會結果按照索引列有序呢?這還要從數據庫內部的運行機制說起。首先系統會查詢索引表(test_b_indexed_type),該索引表的主鍵是索引列type(通常為了保證主鍵唯一性,type後面會添加一個id後綴),通過索引列查到Id,然後拿著這些Id去test_b中查詢最終結果。為了最高效,掃描索引表的時候會順著type主鍵往下掃,然後拿掃得的id去“逐個”請求test_b,於是自然就出現了按照索引列有序的結果。
當Type列的值一致的時候,插入到索引列的數據可以根據Id順序插入到索引表中,保證了當Type一致的時候,會按照Id排序。