程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> (2)mysql優化之使用索引優化查詢

(2)mysql優化之使用索引優化查詢

編輯:MySQL綜合教程

(2)mysql優化之使用索引優化查詢


概述

??索引是數據庫優化中最常用的也是最重要的手段之一。該篇看看索引的分類,使用場景,不能使用的場景等。

索引分類

??索引是在mysql存儲引擎中實現的,而不是在服務器層實現的。索引每種存儲引擎的索引不一定相同。mysql支持4種索引:

B-tree索引:最常見索引,大部分引擎都支持B樹索引。 full-text索引:全文索引。 hash索引:只有memory引擎支持。 R-Tree索引:空間索引是myisam的一種特殊索引,使用比較少。

衍生索引:主鍵,唯一索引,組合索引,前綴索引等。hash索引適合key-value查詢(等值查詢),不適合范圍查詢。

索引 MYISAM引擎 InnoDB引擎 Memory引擎 B-tree索引 支持 支持 支持 full-text索引 支持 - - hash索引 - - 支持 R-tree索引 支持 - -

使用索引的典型場景

1.匹配全值(match the full value)

對索引中所有列都指定具體值,即對索引中的所有列都有等值匹配的條件。

#設置組合索引(rental_date,inventory_id,customer_id)為唯一索引。
EXPLAIN SELECT * FROM rental 
WHERE rental_date='2005-05-25 17:22:10' 
  AND inventory_id=373 
  AND customer_id=343;

匹配全值

2.匹配值的范圍查詢(match a range of values)

對索引值進行范圍查找。

#設置索引idx_fk_customer_id(customer_id)
EXPLAIN SELECT * FROM rental WHERE customer_id >= 373 AND customer_id < 400;

范圍查詢

3.匹配最左前綴(match a leftmost prefix)

僅僅使用索引中的最左邊列進行查詢。比如組合索引(col1,col2,col3)能夠被col1,col1+col2,col1+col2+col3的等值查詢利用到的。

#創建索引idx_payment_date(payment_date,amount,last_update);

EXPLAIN SELECT * FROM payment WHERE payment_date='2006-02-14 15:16:03' AND last_update = '2006-02-15 22:12:32';

匹配最左前綴
從結果可以看出利用了索引,但又row為182行,所有只使用了部分索引。<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KCgoKPHByZSBjbGFzcz0="brush:sql;">EXPLAIN SELECT * FROM payment WHERE amount=3.98 AND last_update='2006-02-15';

匹配最左前綴-2
從結果看出,這次查詢沒有利用索引,進行了全表查找。

4.僅對索引查詢進行查詢(index only query)

當查詢列都在索引字段中。即select中的列都在索引中。

EXPLAIN SELECT last_update FROM payment WHERE payment_date='2005-08-19 21:21:47' AND amount=4.99;

不用回表查找
extra部分Using index,說明不需要通過索引回表,Using index就是平時說的覆蓋索引掃描(即找到索引,就找到了要查詢的結果,不用再回表查找了)。

5.匹配列前綴(match a column prefix)

僅僅使用索引的第一列,並且只包含索引第1列的開頭部分進行查找。

#創建索引idx_title_desc_part(title(10),description(20));

EXPLAIN SELECT title FROM film_text WHERE title LIKE 'AFRICAN%';

匹配前綴索引

6.索引部分等值匹配,部分范圍匹配

EXPLAIN SELECT inventory_id FROM rental WHERE rental_date='2006-02-14 15:16:03' AND customer_id >= 300 AND customer_id <=400;

這裡寫圖片描述
type=ref,說明使用了索引。

7.列名是索引,column_name is null,使用索引

EXPLAIN SELECT * FROM payment WHERE rental_id IS NULL;

null

索引存在但不能使用索引的典型場景

1.以%開頭的like查詢

EXPLAIN SELECT * FROM actor WHERE last_name LIKE '%NI%';

這裡寫圖片描述

#優化
EXPLAIN SELECT * FROM (SELECT actor_id FROM actor WHERE last_name LIKE '%NI%')a,actor b WHERE a.actor_id=b.actor_id;

這裡寫圖片描述

2.數據類型出現隱式轉化,不會使用索引

EXPLAIN SELECT * FROM actor WHERE last_name=1;

這裡寫圖片描述

#使用索引
EXPLAIN SELECT * FROM actor WHERE last_name='1';

這裡寫圖片描述

3.組合索引,不滿足最左原則,不使用符合索引

EXPLAIN SELECT * FROM payment WHERE amount=3.98 AND last_update='2006-02-15 22:12:32';

這裡寫圖片描述

4.估計使用索引比全表掃描還慢,則不要使用索引

如查詢以“S”開頭的標題的電影,返回記錄比例比較大,mysql預估索引掃描還不如全表掃描。

EXPLAIN SELECT * FROM film_text WHERE title LIKE 'S%';

這裡寫圖片描述

5.用or分割條件,若or前後只要有一個列沒有索引,就都不會用索引

EXPLAIN SELECT * FROM payment WHERE customer_id=203 OR amount=3.96;

這裡寫圖片描述

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved