
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
索引是我们在建立软件后台数据库的时候需要添加的一项功能,而今天我们就通过案例分析来了解一下,数据库索引优化都有哪些特点。
优先使用自增key作为主键
前面的分析中,假设用4B的自增key作为索引,则m可达到512,层高仅有3。使用自增的key有两个好处:
自增key一般为int等整数型,key比较紧凑,这样m可以非常大,而且索引占用空间小。极端的例子,如果使用50B的varchar(包括长度),那么m = 4 * 1024 / 54m = 75.85 ~= 76,深度大 log(76/2)(10^7) = 4.43 ~= 5,再加上cache缺失、字符串比较的成本,时间成本增加较大。同时,key由4B增长到50B,整棵索引树的空间占用增长也是极为恐怖的(如果二级索引使用主键定位数据行,则空间增长更加严重)。
自增的性质使得新数据行的插入请求必然落到索引树的右侧,发生节点分裂的频率较低,理想情况下,索引树可以达到“满”的状态。索引树满,一方面层高更低,一方面删除节点时发生节点合并的频率也较低。优化经历:
猴子曾使用varchar(100)的列做过主键,存储containerId,过了3、4天100G的数据库就满了,DBA小姐姐邮件里委婉表示了对我的鄙视。。。之后增加了自增列作为主键,containerId作为unique的二级索引,时间、空间优化效果相当显著。
左前缀匹配
索引可以简单如一个列(a),也可以复杂如多个列(a, b, c, d),即联合索引。如果是联合索引,那么key也由多个列组成,同时,索引只能用于查找key是否存在(相等),遇到范围查询(>、<、between、like左匹配)等就不能进一步匹配了,后续退化为线性查找。因此,列的排列顺序决定了可命中索引的列数。
如有索引(a, b, c, d),查询条件a = 1 and b = 2 and c > 3 and d = 4,则会在每个节点依次命中a、b、c,无法命中d。也就是左前缀匹配原则。
=、in自动优化顺序
不需要考虑=、in等的顺序,mysql会自动优化这些条件的顺序,以匹配尽可能多的索引列。
如有索引(a, b, c, d),查询条件c > 3 and b = 2 and a = 1 and d < 4与a = 1 and c > 3 and b = 2 and d < 4等顺序都是可以的,MySQL会自动优化为a = 1 and b = 2 and c > 3 and d < 4,依次命中a、b、c。
索引列不能参与计算
有索引列参与计算的查询条件对索引不友好(甚至无法使用索引),如from_unixtime(create_time) = '2014-05-29'。
原因很简单,如何在节点中查找到对应key?如果线性扫描,则每次都需要重新计算,成本太高;如果二分查找,则需要针对from_unixtime方法确定大小关系。
因此,索引列不能参与计算。上述from_unixtime(create_time) = '2014-05-29'语句应该写成create_time = unix_timestamp('2014-05-29')。
能扩展就不要新建索引
如果已有索引(a),想建立索引(a, b),尽量选择修改索引(a)为索引(a, b)。
新建索引的成本很容易理解。而基于索引(a)修改为索引(a, b)的话,MySQL可以直接在索引a的B+树上,经过分裂、合并等修改为索引(a, b)。
不需要建立前缀有包含关系的索引
如果已有索引(a, b),则不需要再建立索引(a),但是如果有必要,则仍然需考虑建立索引(b)。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!