索引、分區

mysql索引:
例:建立索引:KEY `ind_kn_ex_type` (`type_id`,`knowledge_id`,`exam_id`) USING BTREE

要想強制MySQL使用或建議使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
例:SELECT * FROM ti_novice_knowledge_relevance IGNORE INDEX(ind_kn_ex_type) WHERE  id = 1

組合索引的最左規則:where條件不看順序、只要包含最左條件依次往右即可,
例:SELECT * FROM ti_novice_knowledge_relevance WHERE type_id = 3 AND exam_id ='19d53385-746d-4a3d-8354-9d645508514a'  AND knowledge_id ='2502784f-704c-e3ae-0c6b-8390f2b40e9a' 命中組合索引的三個索引值
SELECT * FROM ti_novice_knowledge_relevance WHERE type_id = 3  AND knowledge_id ='2502784f-704c-e3ae-0c6b-8390f2b40e9a' 命中組合索引的2個索引值
SELECT * FROM ti_novice_knowledge_relevance WHERE type_id = 3 命中組合索引的1個索引值
SELECT * FROM ti_novice_knowledge_relevance WHERE  exam_id ='19d53385-746d-4a3d-8354-9d645508514a'  AND knowledge_id ='2502784f-704c-e3ae-0c6b-8390f2b40e9a' 未命中索引
SELECT * FROM ti_novice_knowledge_relevance WHERE  exam_id ='19d53385-746d-4a3d-8354-9d645508514a'   未命中索引


當查詢字段 *時/全部爲索引字段時  (select查詢字段不必遵循最左原則、where後面聚集索引、唯一索引、一般索引的explain類型不一樣):
1、聚集索引:
SELECT * FROM ti_novice_knowledge_relevance WHERE  id = 1;  const
SELECT id FROM ti_novice_knowledge_relevance WHERE  id = 1;  const
2、唯一索引:只是當一般索引的type爲ref時,唯一索引type爲eq_ref
3、一般索引:
SELECT * FROM ti_novice_knowledge_relevance WHERE type_id = 3;  ref
SELECT id,exam_id FROM ti_novice_knowledge_relevance WHERE  type_id = 3;  ref

SELECT * FROM ti_novice_knowledge_relevance WHERE type_id >= 3;  all(會根據範圍的大小最大變爲all最小變爲range) >= <= > < 等都一樣  !=(index或者all與like一樣)
SELECT id,exam_id FROM ti_novice_knowledge_relevance WHERE type_id >= 3;  range(會根據範圍的大小最大變爲index最小變爲range)

SELECT * FROM ti_novice_knowledge_relevance WHERE type_id LIKE '%3%';  ALL
SELECT id,exam_id FROM ti_novice_knowledge_relevance WHERE  type_id LIKE '%3%';  index

SELECT * FROM ti_novice_knowledge_relevance WHERE type_id IS NULL;  ref
SELECT id,exam_id FROM ti_novice_knowledge_relevance WHERE type_id IS NULL;  ref

SELECT * FROM ti_novice_knowledge_relevance WHERE type_id IS NOT NULL;  ALL
SELECT id,exam_id FROM ti_novice_knowledge_relevance WHERE type_id IS NOT NULL;  index

SELECT id,exam_id FROM ti_novice_knowledge_relevance WHERE exam_id ='19d53385-746d-4a3d-8354-9d645508514a';  index(當where條件在索引中(組合索引的非頭部字段)並且select後面跟的只有索引相關字段,會是index)
SELECT * FROM ti_novice_knowledge_relevance WHERE exam_id ='19d53385-746d-4a3d-8354-9d645508514a';  ALL

SELECT * FROM ti_novice_knowledge_relevance WHERE type_id IN ('4','3');  range
SELECT id,exam_id FROM ti_novice_knowledge_relevance WHERE type_id = '3' OR  type_id = '4' OR  type_id = '5';  range(or連接的條件一致會命中索引,條件字段不一樣or前面和後面的都不會命中索引)

針對union測試:
索引有:
  KEY `ind_operateId` (`operate_id`),
  KEY `ind_empCode_waybillNo` (`emp_code`,`waybill_no`),
例:
SELECT emp_code,operate_id FROM ti_novice_simulate_operate_process_record WHERE emp_code = ''
UNION
SELECT emp_code,operate_id FROM ti_novice_simulate_operate_process_record WHERE operate_id = '' ; 2個都命中索引

SELECT emp_code,operate_id FROM ti_novice_simulate_operate_process_record WHERE
emp_code = '' or operate_id = ''; 未命中索引(or連接的條件一致會命中索引,條件字段不一樣or前面和後面的都不會命中索引)


索引的一個優點是可以 降低分組、排序的時間:

(1)排序
說對排序的影響,就不得不說一下索引本身的特點,就是索引是對字段進行排序的,語句如下:
select ... from A order by ID
同時,我們對A表的ID字段創建了索引,那麼在執行sql過程中,可以直接從索引獲取ID的值,而且這個值是已經排過序的,就省了排序的時間,速度就能提高。

(2)分組
對分組的影響,要看不同的情況,分組對應sql語句中的group by 操作,但是group by具體實現的時候,有hash、order 共兩種算法。
對於order算法來說,因爲是通過排序來實現分組,那麼有了索引後,可以省去排序的過程,自然能縮短分組時間。
對於hash算法,是通過在 內存建hash表+探查 兩個過程來實現的,所以 和排序沒有關係,所以索引的排序特性,並不能縮短分組時間。

這裏把sql執行的過程,抽象爲:讀取數據+操作(這裏是分組)+返回結果,這3個過程。
創建索引後,運用索引中包含字段值的這個特點,可以起到覆蓋查詢的作用,查詢直接從索引取數而非全表掃描,可以降低讀取數據的時間。
這樣雖然分組這個操作沒有縮短時間,但是讀取時間少了,所以,整體是有提高的。

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