最近發現一個平時經常忽略的問題,就是MySQL查詢出來的結果的排序問題。
之前一直認為,如果在sql語句中沒有加特定的order by條件,那么查詢出來的數據就應該是按照主鍵(即插入順序)排序的。但是,今天在項目中拿數據時發現並沒有按照“我以為”的方式排序,就研究了下,發現按照什么方式排序與所查詢的字段、索引等都有關系的。
因為項目中基本都使用InnoDB引擎,所以就不考慮其他引擎了,自己測試了下:
首先創建測試表(隨便寫了下sql語句,不要細究什么沒有判斷表是否存在的問題,哈哈)
小心機一下,字段盡量不要允許為NULL
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(100) DEFAULT '' NOT NULL, `age` int(5) DEFAULT 0 NOT NULL, PRIMARY KEY (`id`), KEY `age` (`age`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
插入一些測試數據
INSERT INTO test(name, age) VALUES('張三',2); INSERT INTO test(name, age) VALUES('李四',20); INSERT INTO test(name, age) VALUES('王五',50); INSERT INTO test(name, age) VALUES('趙劉',33); INSERT INTO test(name, age) VALUES('奔馳',19); INSERT INTO test(name, age) VALUES('寶馬',7); INSERT INTO test(name, age) VALUES('奧迪',21); INSERT INTO test(name, age) VALUES('雷車',22); INSERT INTO test(name, age) VALUES('蘭博',18); INSERT INTO test(name, age) VALUES('賓利',99); INSERT INTO test(name, age) VALUES('夏利',67);
測試1:無條件查詢前5條記錄
SELECT * FROM test LIMIT 5
結果如下
測試2:無條件查詢前5條age
select age from test limit 5;
測試3:無條件查詢前5條記錄,結果集根據age排序
select * from test order by age;
分別使用explain命令對這三條sql語句進行分析:
可以看到:
第1、3兩條select * 語句的type都是ALL,說明進行的是全表掃描,沒有用到索引。(Using filesort情況該如何優化?)
第2條select age 語句的type是index,說明使用的索引進行的掃描;且key是age,說明使用的索引列是age。
總結:
如果在sql語句中不指定order by排序條件,那么得到的結果集的排序順序是與查詢列有關的。因為不同的查詢列可能會用到不同的索引,從而導致順序不同。根據上面的情況:查詢所有列時是根據id排序的;只查詢age列時是根據age列(age列是索引)排序的;而加上order by age后,因為待排序內容不能由所使用的索引直接完成排序,所以要進行文件排序,具體原因就不深究了。
看網上大神的說法是:沒有條件的情況下,數據庫默認排序順序是不好確定的,也不應該決定於什么因素,不同的數據庫實現不同.只能用order by 來限定。
反正,不要迷信mysql默認會按照你以為的順序排序,想要排序就先給你想要排序的字段創建索引(提高效率),然后再order by這個字段進行排序。
轉載自:https://blog.csdn.net/qq_35383263/article/details/81433693