MySQL索引结构
一.MySQL索引,数据结构为啥用B+树
啥是B+树?
他有了一个概念叫叶子节点。
把所有的数,进行了一个链表的排序,从小到大进行排序。它和B树有一个共同特点,一个节点可以同时存储两个值,树的高度很低,同时还解决了回溯查找,上面的树成为非叶子节点,下面的链表1是叶子节点,凡是树上出现的数字都会出现在叶子节点里。
1.为啥不用哈希索引?
因为hash是无序的,所以不能进行范围查找,还有排序的时候,也没办法用hash索引的哈希值去排序,因为他的值本来就是无序的。需要进行全表扫描
2.为啥不用平衡二叉树呢?
平衡二叉树有个特点,就是左子树的值要小于右子树,数据量小的话,查询速度快,随着树越高,查询速度越来越慢,
如果要查找一个大于10的数,需要回溯去查,如果大于10的数很多,那它的效率就很慢
3.为啥不用B树?
B树一个特点,一个节点能同时存两个值。
同样的数据量,比平衡二叉树,高度低,意味着查找速度比二叉树快。
但是如果要查找一个值,还是需要回溯查找
二.MySQL索引为啥会在某些情况下失效?失效的原理是啥?
索引失效的情况主要针对联合索引。
单值索引和联合索引有哪些不同,联合索引的一个节点上有两个键值对,
(a,b)联合索引
(1,1)(1,2)(2,1)(2,4)
特点一:左边是a,a是有序的,b是无序的
特点二: 左边a相等的情况下,b是有序的
1.最佳左前缀法则
如果一个联合索引 abc ,sql查询条件 a=1,b=2. 这个查找方式遵循最佳左前缀法则,它是怎么查的呢,
a相等的基础上用二分查找法去查找b,b也是有序的。
如果 条件只有b=2 它是怎么查的呢?
在没有a的情况下,b肯定是无序的。那怎么样在b无序的条件下找到要查询的值呢? 所以它就开始全表扫描,有序不只指叶子节点的有序,也指非叶子节点的有序。如果整个B+树上的值都是无序的,那就没有办法通过二分查找法1去查找
2.大于号右边的索引会失效
a大于1 并且 b 等于2 ,a是有序的,b是无序的,它的非叶子节点也是无序的。所以不能通过二分查找法来查找。
如果a等于1 并且 b等于2 那就用到最佳左前缀法则
3.使用like索引会失效
%放右边(前缀)
%放左边(后缀)
前缀:是去查找以1开头的数据
字符串的首字符是有顺序的 ,字符串的尾部和中部是没有顺序的
在没有顺序的二叉树上查找是查找不到的
这个就是like失效的原理
同理 or为什么会失效 in为什么会失效 !=为什么会失效
都是因为在没有顺序的数据中,去查找数据
三.二分法代码实现
$array = [1,2,3,10];
$target = 3;
$low = 0;
$high = count($array)-1;
function binary_search($array ,$low,$high,$target)
{
$mid = intval(($low+$high)/2);
while($low<=$high)
{
if($array[$mid] == $target)
{
return true;
}
elseif($array[$mid] > $target)
{
return binary_search($array,$low,$mid-1,$target);
}
else
{
return binary_search($array,$mid+1,$high,$target);
}
}
return false;
}