◆只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。
◆不要在列上进行运算 (对索引列使用函数进行计算,就使用不到索引了)
select * from users where YEAR(adddate)<2007; 将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成
select * from users where adddate<‘2007-01-01’;
◆不使用NOT IN和<>操作
mysql innodb索引与算法
索引的本质: 索引是帮助mysql高效获取数据的排好序的数据结构. 索引数据结构: 二叉树,hash索引, b tree, b+树(mysql/oracle都是是b+树).
索引最左前缀原则. abc联合索引 a+c断掉b,只能用到a.
abc联合索引可以支持a | a,b | a,b,c 3种组合进行查找,但不支持 b,c进行查找 .
select * from t where a=1 and c=1; #这样可以利用到定义的索引(a,b,c),但只用上a索引,b,c索引用不到
select * from t where b=1 and c=1; # bc用不到索引
B+树:
1.非叶子节点不存储data,只存储索引,可以放更多的索引
2.叶子节点包含所有索引字段
3.叶子节点用指针有序连接,提高区间访问的性能,叶子节点存储data, 高度为3的b+树就可以存千万级别.
explain执行计划:
1.id列: id列的编号是select的序列号, 有几个select就有几个id , id越大优先执行,id为null最后执行
2.select type列
select type列表示对应行是简单还是复杂的查询.
1>simple : 简单查询.查询不包含子查询和union
2>primary:复杂查询中最完成的select
3>subquery:包含在select中的子查询(不在from子句中)
4>derived:包含在from子句中的子查询,mysql会将结果存放在一个临时表中(也成为派生表derived的英文单词含义)
用下面例子来理解
explain select (select 1 from actor whre id =1) from (select * from film where id=1) der;
3.table列
1>这一列表示explain的一行正在访问哪个表,当from子句中有子查询时,table列是<derivenN>格式,表示当前查询依赖id=N的查询,于是先执行id=N的查询
2>当有union时, UNION RESULT的table列的值为<union1,2> 1和2表示参与union的select行id
4.type列 表示访问类型,mysql决定如何查找表中的行,查找数据行记录的额大概范围.
null的是使用min(id)效率也高. system只有一条记录>const主键>eq ref二级索引>ref>range>index全表>all
Innodb:5.6后默认支持的存储引擎,支持事务,行级锁,MVCC等,大量应用于互联网公司
MyISAM存储引擎索引实现 MyISAM索引文件和数据文件是分离的(非聚集)
InnoDB存储引擎索引实现:
InnoDB索引实现(聚集)
表数据文件本身就是按B+Tree组织的一个索引结构文件
聚集索引-叶节点包含了完整的数据记录
1.聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据
2.非聚簇索引:
将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,
当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因
为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?
为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)
索引最左前缀原理
事务具有4个特征,分别是原子性(Atomicity)、一致性(Consistent)、隔离性(Isolation)和持久性(Durable),简称事务的ACID特性;
事务隔离级别:RU RR RC(可重复读,默认mysql) serializable
我们都知道HashMap初始容量大小为16,一般来说,当有数据要插入时,都会检查容量有没有超过设定的thredhold,
如果超过,需要增大Hash表的尺寸,进行扩容
但是这样一来,整个Hash表里的元素都需要被重算一遍。这叫rehash,这个成本相当的大。
ArrayList 在JDK1.8中,如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时(即添加第一个元素时),
才真正分配容量,默认分配容量为10;当容量不足时(容量为size,添加第size+1个元素时),
先判断按照1.5倍(位运算)的比例扩容能否满足最低容量要求,若能,则以1.5倍扩容,否则以最低容量要求进行扩容。
10 15 22
浅谈HashMap为什么不安全
首先是无论JDK1.7还是1.8都会产生的不安全因素:
hashmap1.7 死循环,并发插入并不是发生在put操作时,而是发生在扩容时。
在默认情况下,数组大小为16,loadFactor为0.75,
也就是说当HashMap中的元素超过16\0.75=12时,
会把数组大小扩展为2*16=32,
hashmap1.8的优化,
1.数据结构方面, 引入了红黑树, 当数组长度大于64, 链表长度大于8,转为红黑树,反之链表长度小于6,又讲红黑树变为链表, 不会让链表太长, 提升查询速度.
2.hash冲突处理的优化: 头插改尾插法. 好处是a.避免扩容后,链表产生相对位置倒序;b.避免并发环境下,扩容产生循环链表,导致死循环.
3.扩容寻址算法的优化
红黑树的3个属性: 根属性, 红属性, 黑属性