Mysql索引優化_ORDER BY中索引的使用

在實際的業務中我們經常會用到排序的場景。但是很多時候用了排序之後,效率就會降低很多。
首先說下Mysql的排序方式,在我所知的是有兩種:

  • 一種是排序的字段是有索引的,因爲索引是有序的,所以不需要另外排序,
  • 另一種是排序的字段沒有索引,所以需要對結果進行排序,這種情形下如果我們EXPLAIN分析的話就會出現 Extra: Using filesort

如果用到的了using filesort對結果進行排序會使效率很大程度上的受影響。所以我們儘量使排序能用到索引。那麼什麼時候才能使用到索引呢,下面舉幾個簡單的例子。有表結構如下:

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;
這個索引也是可以引用索引排序的。


下面是一些不能使用索引排序的例子:
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 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;

這些只是一些簡單的示例,在實際場景中業務會更復雜,也會存在多張表的時候。這個時候就需要我們實際去分析問題了。只要是知道了基本原理,其他的都是順藤摸瓜。
bVbuD9k?w=258&h=258

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章