索引、分区

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个过程。
创建索引后,运用索引中包含字段值的这个特点,可以起到覆盖查询的作用,查询直接从索引取数而非全表扫描,可以降低读取数据的时间。
这样虽然分组这个操作没有缩短时间,但是读取时间少了,所以,整体是有提高的。

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