@zero1036
2018-09-26T09:26:00.000000Z
字数 4752
阅读 1264
Mysql
原则
如下:有队列[2,3,5,6,7,8]
6
/ \
3 7
/ \ \
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
数据库中使用最为频繁的一种索引。
(1)所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;(只有根节点存储关键字最后树的末梢才有值)
(2)非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层。(非根节点,存储的其实是指向根节点的索引)
(3) 因为前两点,所以不可能在非叶子结点存数据。(区别B-的第三条)
(4)根节点横向也有链指针(方便快速顺藤摸瓜嘛,没这个指针,就算下一个取的值是挨着的邻居,也得跑个圈才能拿到)
本文来自 时而宁靜 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/ty_hf/article/details/53526822?utm_source=copy
1、左条件范围查询,右条件全等:
左条件范围值在少于等于5个时,可以命中索引,连接类型为range,例如:
explain
select * from red_packet where business_id in ('1260809','1260807','dfd','2934','sdfw','sdfds') and activity_code = 'investRed'
# id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
'1', 'SIMPLE', 'red_packet', NULL, 'range', 'business_id', 'business_id', '172', NULL, '6', '100.00', 'Using index condition'
关于explain分析:https://www.jianshu.com/p/e5232bdf3290
示查询中每个select子句的类型
显示这一行的数据是关于哪张表的,有时不是真实的表名字,看到的是derivedx(x是个数字,我的理解是第几步执行的结果)
表示MySQL在表中找到所需行的方式,又称“访问类型”。
连接类型:分别为:system/const/eq_ref/ref/range/index/All,效率从前往后一次递减
select @rowNum:=0
。指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用
该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询
key列显示MySQL实际决定使用的键(索引)
如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)
不损失精确性的情况下,长度越短越好
表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数
该列包含MySQL解决查询的详细信息,有以下几种情况:
范围查询与常量转换示例:https://blog.csdn.net/itas109/article/details/79150550
连接类型与索引
explain
select * from suzaku_event_log
#const,id为主键索引,表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
where id = '123'
#range,id为主键索引,可以在索引上按指定的范围进行检索
where id in ('123','124')
#all,source_id非索引,全表搜索
where source_id in ('sid123')
#ref,customer_id为普通索引,可以在索引上按指定的范围进行检索
where customer_id = 'cid123'
#range,customer_id与event_date组合索引,可以在索引上按指定的范围进行检索
where customer_id = 'cid124' and '2018-09-06 00:00:00' <= event_date and event_date <= '2018-09-06 01:00:00'
#range,customer_id与event_date组合索引,最左使用 = < 、<=#.可以在索引上按指定的范围进行检索,
where customer_id > 'cid124' and '2018-09-06 00:00:00' <= event_date and event_date <= '2018-09-06 01:00:00'
#all,右条件非索引范围查询,全表索引
where customer_id = 'cid124' and source_id < 'sid123'
ON 条件(“A LEFT JOIN B ON 条件表达式”中的ON)用来决定如何从 B 表中检索数据行。如果 B 表中没有任何一行数据匹配 ON 的条件,将会额外生成一行所有列为 NULL 的数据,在匹配阶段 WHERE 子句的条件都不会被使用。仅在匹配阶段完成以后,WHERE 子句条件才会被使用。它将从匹配阶段产生的数据中检索过滤。
note1:在使用left(right)join的时候,一定要先给出尽可能多的匹配满足条件,减少where的执行。
note2:注意ON 子句和 WHERE 子句的不同。看以下例子
mysql> SELECT * FROM product LEFT JOIN product_details
ON (product.id = product_details.id)
AND product_details.id=2;
+----+--------+------+--------+-------+
| id | amount | id | weight | exist |
+----+--------+------+--------+-------+
| 1 | 100 | NULL | NULL | NULL |
| 2 | 200 | 2 | 22 | 0 |
| 3 | 300 | NULL | NULL | NULL |
| 4 | 400 | NULL | NULL | NULL |
+----+--------+------+--------+-------+
4 rows in set (0.00 sec)
mysql> SELECT * FROM product LEFT JOIN product_details
ON (product.id = product_details.id)
WHERE product_details.id=2;
+----+--------+----+--------+-------+
| id | amount | id | weight | exist |
+----+--------+----+--------+-------+
| 2 | 200 | 2 | 22 | 0 |
+----+--------+----+--------+-------+
1 row in set (0.01 sec)