在實際的業務中咱們常常會用到排序的場景。可是不少時候用了排序以後,效率就會下降不少。
首先說下Mysql
的排序方式,在我所知的是有兩種:sql
EXPLAIN
分析的話就會出現 Extra: Using filesort
若是用到的了using filesort
對結果進行排序會使效率很大程度上的受影響。因此咱們儘可能使排序能用到索引。那麼何時才能使用到索引呢,下面舉幾個簡單的例子。有表結構以下:spa
CREATE TABLE `student` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `first_name` varchar(20) NOT NULL, `last_name` varchar(20) NOT NULL, `created_at` date NOT NULL, `score` int(3) NOT NULL DEFAULT '0', `updated_at` timestamp NOT NULL, PRIMARY KEY (`id`), KEY `time_sorce_name` (`created_at`,`score`,`first_name`) ) ENGINE=InnoDB AUTO_INCREMENT=6811477 DEFAULT CHARSET=utf8
能夠看到這個表中已經有6811477
條數據了。
下面咱們來看一些查詢:SELECT * FROM student WHERE created_at='2019-07-10' ORDER BY score;
WHEREcreated_at
條件跟排序字段score
組成了一個符合最左索引條件的組合,因此是能夠用到索引的。
可是若是咱們把上面的查詢改一下。SELECT * FROM student WHERE created_at='2019-07-10' ORDER BY score,first_name;
這個索引也是能夠引用索引排序的。code
下面是一些不能使用索引排序的例子:SELECT * FROM student WHERE created_at<'2019-07-10' ORDER BY score;
那麼這個狀況是不能使用到索引的,由於查詢的一個列是一個範圍查詢,因此能用到的索引列也就只有第一列,而排序中的score
列是不能使用到索引的。
下面這個查詢也是不能使用到索引排序的,由於排序字段中引用了一個不在索引中的列SELECT * FROM student WHERE created_at<'2019-07-10' ORDER BY score,last_name;
下面這個查詢也是不能使用到索引排序的,由於排序字段跟查詢條件不能組成符合索引的最左條件SELECT * FROM student WHERE created_at<'2019-07-10' ORDER BY first_name;
下面這個查詢也是不能使用到索引排序的,由於用到IN
查詢也是一個範圍查詢SELECT * FROM student WHERE created_at<'2019-07-10' and score IN(20,80) ORDER BY first_name;
排序
這些只是一些簡單的示例,在實際場景中業務會更復雜,也會存在多張表的時候。這個時候就須要咱們實際去分析問題了。只要是知道了基本原理,其餘的都是順藤摸瓜。
索引