[关闭]
@zero1036 2018-09-26T09:26:00.000000Z 字数 4752 阅读 1270

mysql索引及join查询

Mysql


索引

数据结构

二叉查找树

原则

  1. 左叶 < 根
  2. 右叶 > 根
  3. 可以任务构造

如下:有队列[2,3,5,6,7,8]

  1. 6
  2. / \
  3. 3 7
  4. / \ \
  5. 2 5 8

目标找到5,从根6入手,找小的,得到左叶3,找大的,得到右叶5。总共寻觅3次。
可以得出,要找出队列中所有的值,需要N次:N = 3 + 2 + 3 + 1 + 2 + 3 = 14 / 6 = 2.33
如果通过顺序查询,需要N = (1 + 2 + 3 + 4 + 5 + 6) / 6 = 3.3

B+Tree

数据库中使用最为频繁的一种索引。

(1)所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;(只有根节点存储关键字最后树的末梢才有值)
(2)非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层。(非根节点,存储的其实是指向根节点的索引)
(3) 因为前两点,所以不可能在非叶子结点存数据。(区别B-的第三条)
(4)根节点横向也有链指针(方便快速顺藤摸瓜嘛,没这个指针,就算下一个取的值是挨着的邻居,也得跑个圈才能拿到)


本文来自 时而宁靜 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/ty_hf/article/details/53526822?utm_source=copy


命中索引条件

1、左条件范围查询,右条件全等:

左条件范围值在少于等于5个时,可以命中索引,连接类型为range,例如:

  1. explain
  2. select * from red_packet where business_id in ('1260809','1260807','dfd','2934','sdfw','sdfds') and activity_code = 'investRed'
  3. # id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
  4. '1', 'SIMPLE', 'red_packet', NULL, 'range', 'business_id', 'business_id', '172', NULL, '6', '100.00', 'Using index condition'

explain

关于explain分析:https://www.jianshu.com/p/e5232bdf3290

select_type

示查询中每个select子句的类型

table

显示这一行的数据是关于哪张表的,有时不是真实的表名字,看到的是derivedx(x是个数字,我的理解是第几步执行的结果)

type连接类型

表示MySQL在表中找到所需行的方式,又称“访问类型”。
连接类型:分别为:system/const/eq_ref/ref/range/index/All,效率从前往后一次递减

possible_keys

指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用

该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

Key

key列显示MySQL实际决定使用的键(索引)

如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)

不损失精确性的情况下,长度越短越好

ref

表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

rows

表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数

Extra

该列包含MySQL解决查询的详细信息,有以下几种情况:

explain总结:


范围查询与索引

范围查询与常量转换示例:https://blog.csdn.net/itas109/article/details/79150550

连接类型与索引

  1. explain
  2. select * from suzaku_event_log
  3. #const,id为主键索引,表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
  4. where id = '123'
  5. #range,id为主键索引,可以在索引上按指定的范围进行检索
  6. where id in ('123','124')
  7. #all,source_id非索引,全表搜索
  8. where source_id in ('sid123')
  9. #ref,customer_id为普通索引,可以在索引上按指定的范围进行检索
  10. where customer_id = 'cid123'
  11. #range,customer_id与event_date组合索引,可以在索引上按指定的范围进行检索
  12. where customer_id = 'cid124' and '2018-09-06 00:00:00' <= event_date and event_date <= '2018-09-06 01:00:00'
  13. #range,customer_id与event_date组合索引,最左使用 = < 、<=#.可以在索引上按指定的范围进行检索,
  14. where customer_id > 'cid124' and '2018-09-06 00:00:00' <= event_date and event_date <= '2018-09-06 01:00:00'
  15. #all,右条件非索引范围查询,全表索引
  16. where customer_id = 'cid124' and source_id < 'sid123'

join on

on与where的执行顺序

ON 条件(“A LEFT JOIN B ON 条件表达式”中的ON)用来决定如何从 B 表中检索数据行。如果 B 表中没有任何一行数据匹配 ON 的条件,将会额外生成一行所有列为 NULL 的数据,在匹配阶段 WHERE 子句的条件都不会被使用。仅在匹配阶段完成以后,WHERE 子句条件才会被使用。它将从匹配阶段产生的数据中检索过滤。

note1:在使用left(right)join的时候,一定要先给出尽可能多的匹配满足条件,减少where的执行。

note2:注意ON 子句和 WHERE 子句的不同。看以下例子

  1. mysql> SELECT * FROM product LEFT JOIN product_details
  2. ON (product.id = product_details.id)
  3. AND product_details.id=2;
  4. +----+--------+------+--------+-------+
  5. | id | amount | id | weight | exist |
  6. +----+--------+------+--------+-------+
  7. | 1 | 100 | NULL | NULL | NULL |
  8. | 2 | 200 | 2 | 22 | 0 |
  9. | 3 | 300 | NULL | NULL | NULL |
  10. | 4 | 400 | NULL | NULL | NULL |
  11. +----+--------+------+--------+-------+
  12. 4 rows in set (0.00 sec)
  13. mysql> SELECT * FROM product LEFT JOIN product_details
  14. ON (product.id = product_details.id)
  15. WHERE product_details.id=2;
  16. +----+--------+----+--------+-------+
  17. | id | amount | id | weight | exist |
  18. +----+--------+----+--------+-------+
  19. | 2 | 200 | 2 | 22 | 0 |
  20. +----+--------+----+--------+-------+
  21. 1 row in set (0.01 sec)
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注