索引

索引


概述

  • 索引定义:索引(Index)是帮助MySQL高效获取数据的数据结构
  • 索引本质:索引是数据结构
  • 索引描述:在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构,就是索引
  • 索引的最好的备选数据列是那些出现在WHERE子句、join子句、ORDER BY或GROUP BY子句中的列。仅仅出现在SELECT关键字后面的输出数据列列表中的数据列不是很好的备选列
  • 索引分类:
    • 单列索引:一个索引包含一列,一个表可以包含多个单列索引
      • 普通索引:
      • 唯一索引:可以为NULL,其他与主键索引相似
      • 主键索引:不可以为NULL
    • 联合索引:一个组合索引包含两个或两个以上的列

相关操作

创建索引

// 语法一
create INDEX index_name on table_name(column_name);  
// 示例
CREATE INDEX account_Index ON `award`(`account`); 
-- 注意字段上的符号,为数字1与TAB间之间的按钮,不是单引号

// 语法二
alter table table_name add INDEX index_name(column_name);  
// 示例
ALTER TABLE award ADD INDEX account_Index(`account`);  

// 语法三:建表时带有辅助索引(与主键索引相区别)
CREATE TABLE `p2p_td_project_advance_repayment` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `repayment_date` date NOT NULL COMMENT '还款日期',
  `create_time` datetime NOT NULL COMMENT '记录创建时间',
  PRIMARY KEY (`id`),
  KEY `idx_repayment_date` (`repayment_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='提前还款表';

// 语法四:创建指定类型的索引
// 普通索引,索引名称:index_name(name为列名)
alter table table_name add index index_name (column_list) ;
// 唯一索引,索引名称:uniq_idx_name(name为列名)
alter table table_name add unique uniq_name(column_list) ;
// 主键索引(通常建表时直接指定主键)
alter table table_name add primary key primary_name(column_list) ;
// 复合索引,索引名称:union_index_name1_name2(复合索引,按照最左匹配原则,按照字段的使用频率从左至右依次递减)
alter table table_name add index index_name_a_b (column_list_a,column_list_b) ;

删除索引

DROP INDEX IndexName ON `TableName`

查看索引

show INDEX from `TableName`

索引实现原理

B-Tree

基于 InnoDB 存储引擎的索引实现原理 与 基于 MyISAM 存储引擎的索引实现原理
存储引擎InnoDBMyISAM
存储结构数据文件(主键索引与数据记录的组合)、日志文件表定义文件、数据文件、索引文件
数据结构B+TreeB+Tree
索引类型聚集索引非聚集索引
叶子节点的键值KEY表的主键索引的相应字段的值
叶子节点的值域DATA完整的数据记录数据记录的地址(数据文件中的对应行数据的物理地址)
辅助索引DATA域主键索引的键值(即若通过辅助索引检索,需检索两次,一次是查找对应的主键,一次是根据主键查找对应的数据行)同主键索引,存储数据记录的地址(因为索引文件与数据文件是分开的)

问题:
  • InnoDB存储引擎中的辅助索引文件如何存放?
  • InnoDB存储引擎若表中主键非主键自增或无主键,数据文件中的主键如何处理?

Hash


优势

  • 索引加快了检索的速度;在索引文件中检索,不必全表逐行比较

劣势

  • 减慢了插入和删除的速度,同时还减慢了更新被索引的数据列中的值的速度。也就是说,索引减慢了大多数涉及写操作的速度。发生这种现象的原因在于写入一条记录的时候不但需要写入数据行,还需要改变所有的索引。数据表带有的索引越多,需要做出的修改就越多,平均性能的降低程度也就越大
  • 索引会花费磁盘空间,多个索引相应地花费更多的磁盘空间。这可能导致更快地到达数据表的大小限制;在InnoDB的共享表空间中分配的所有表都竞争使用相同的公共空间池,因此添加索引会更快地耗尽表空间中的存储

建索引的几大原则

4.1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
4.2.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
4.3.尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录
4.4.索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ‘2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(‘2014-05-29’);
4.5.尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可


参考资料

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值