iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL为数据表建立索引的原则详解
  • 869
分享到

MySQL为数据表建立索引的原则详解

2024-04-02 19:04:59 869人浏览 安东尼
摘要

目录1.索引是什么?2.索引的优点?3.索引的缺点?4.在建立索引的时候,都有哪些需要考虑的因素呢?1、只为用于搜索、排序、分组的列创建索引2、索引列的类型尽量小3、为列前缀建立索引

面试题:

  • 索引是什么?
  • 索引的优点?
  • 索引的缺点?
  • 在建立索引的时候都有哪些需要考虑的因素呢?
  • 为数据表建立索引的原则有哪些?
  • 什么是索引覆盖?
  • 非聚簇索引一定会回表查询吗?

1. 索引是什么?

索引是帮助我们实现快速查询数据库数据结构
在很多时候,表中存放的记录非常的多,需要用到好多的数据页来存放这些记录,在很多页中查找记录可以分为2个步骤:

1、定位到记录所在的页

2、从所在页内查找相应的记录

在没有索引的情况下,无论是根据主键列还是其他列的值进行查找,由于我们不能快速的定位到记录所在的页,所以只能从第一页沿着双向链表一直往下找,因为需要遍历所有的数据页,这种方式超级消耗性能。因此人们期望一种能高效完成搜索的方法,因此就出现了索引,索引就是一种数据结构。

2. 索引的优点?

索引可以让服务器快速的定位到表的指定位置 (索引大大减少了服务器需要需要扫描的数据量)。最常见的B-Tree索引,按照顺序存储数据,所以Mysql可以来做order bygroup by操作(索引可以帮助服务器避免排序和临时表)。因为数据是有序的,所以B-Tree也就会将相关的列值都存储在一起(索引可以将随机io变为顺序IO)。因为索引中存储了实际的列值,所以某些查询值使用索引就能完成全部查询。因此,总结下来的索引的优点为:

1、索引大大减少了服务器需要需要扫描的数据量;

2、索引可以帮助服务器避免排序和临时表;

3、索引可以将随机IO变为顺序IO;

3. 索引的缺点?

1、空间上的代价:

建立索引需要占用物理空间

InnoDB存储引擎默认使用的B+树索引,每建立一个索引,都要为它建立一颗B+树,每一颗B+树的每一个节点都是一个数据页,一个数据页默认会占用16KB的存储空间,而一颗很大的B+树由许多数据页组成,这将占用很大的一片存储空间。

2、时间上的代价:

因为每次对表记录进行增删改,需要进行动态维护索引,导致增删改时间变长

每当对表中的数据进行增删改查操作时,都需要修改各个B+树索引,B+树中的每层节点都按照索引列的值从小到大的顺序组成了双向链表,无论是叶子节点中的记录还是非叶子节点中的记录都按照索引列的值从小到大的顺序排成了单向链表。而增删改查操作可能会对节点和记录的排序造成破坏,所以存储引擎需要额外的时间进行页面分裂、页面回收等操作,以维护节点和记录的顺序。

在执行查询语句前,首先要生成一个执行计划,一般情况下,一条查询语句在执行过程中最多使用一个二级索引,因此,在生成执行计划时需要计算使用不同索引执行查询时所需的成本,最后选取成本最小的那个索引执行查询,如果建立了太多的索引,可能会导致成本分析耗时太多,从而影响查询语句的执行性能。

4. 在建立索引的时候,都有哪些需要考虑的因素呢?

在创建和使用索引是应该注意下列事项:

  • 只为用于搜索、排序、分组的列创建索引;
  • 当列中不重复值的个数在总记录条数中的占比很大时,才为列建立索引;
  • 索引列的类型尽量小;
  • 可以只为索引列前缀创建索引,以减少苏呕心占用的存储空间;
  • 尽量使用覆盖索引进行查询,以毕淼回表操作带来的性能损耗;
  • 让索引列以列名的形式单独出现在搜索条件中;
  • 为了尽可能少的让聚簇索引发生页面分裂的情况,建议让主键拥有anto_increment属性;
  • 定位并删除表中的冗余和重复索引;

建立一张数据库表:

create table single_table(
	id int not auto_increment, 
	key1 varchar(100),         
	key2 int,
	key3 varchar(100),
	key_part1 varchar(100),
	key_part2 varchar(100),
	key_part3 varchar(100),
    common_field varchar(100),
	primary key(id),          # 聚簇索引
	key idx_key1(key1),       # 二级索引
	unique key uk_key2(key2), # 二级索引,而且该索引是唯一二级索引
	key idx_key3(key3),       # 二级索引
	key idx_key_part(key_part1,key_part2,key_part3) # 二级索引,也是联合索引
)Engine=InnoDB CHARSET=utf8;

1、只为用于搜索、排序、分组的列创建索引

我们只为出现在where子句中的列、order bygroup by子句中的列、连接子句中的连接列创建索引。仅出现在查询列表中的列就没有必要建立索引了。

比如下面的查询语句:

select common_field,key_part3 from single_table where key1='a';

我们只需要为出现在where子句中的key1建立索引就可以了,而查询列表中的common_field、key_part3这两个列就没有必要建立索引了。

2、索引列的类型尽量小

在定义表结构时,要显式的指定列的类型。以整数类型为例,有tingint、mediumint、int、bigint这几种,他们占用的存储空间的大小依次递增,他们能表示的整数范围当然也是依次递增。如果想要对某个整数类型的列建立索引,在表示的整数范围允许的情况下,尽量让索引列使用较小的类型,比如使用int就不要用bigint,因为数据类型越小,索引占用的存储空间就越少,在一个数据页内就可以存放更多的记录,磁盘IO带来的性能损耗也就越小,读写效率也就越高。

这个建议对表的主键来说更加适用,因为不仅聚簇索引会存储主键值,所有的二级索引的节点都会存储一份记录的主键值,如果主键使用更小的数据类型,也就意味着能节省更多的存储空间。

3、为列前缀建立索引

一个字符串其实是由若干个字符组成的,假如字符串很长,那么存储这个字符串就会占用很多的存储空间。在为这个字符串所在的列建立索引时,就需要在对应的B+树中,把列的完整字符串存储起来,字符串越长,在索引中占用的存储空间越大。

索引列的字符串前缀其实也是排好序的,所以索引的设计人员设计了一个方案,即只将字符串的前几个字符存放到索引中,也就是说二级索引的记录中只保留字符串的前几个字符。

比如可以这样修改idx_key1索引,让索引中只保留字符串的前10个字符:

alert table single_table drop index idx_key1;
alert table single_table add index idx_key1(key1(10));

然后再执行下面的查询语句:

select * from single_table where key1='abcdefghijklmn';

由于在idx_key1的二级索引记录中只保留字符串的前10个字符,所以我们只能定位到前缀为‘abcdefghij'的二级索引记录,在扫描这些二级索引记录时再判断它们是否满足key1='abcdefghijklmn'条件,当列中存储的字符串包含的字符较多时,这种为列前缀建立索引的方式可以明显减少索引大小。

不过,在只对前缀建立索引的情况下,下面这个查询语句就不能使用索引来完成排序需求了:

select * from single_table order by key1 limit 10;

因为二级索引idx_key1中不包含完整的key1列信息,所以在仅使用idx_key1索引执行查询时,无法对key1列前10个字符相同但其余字符不同的记录进行排序,也就是说,只为列前缀建立索引的方式无法支持使用索引进行排序的需求。

4、覆盖索引

为了彻底告别回表操作带来的性能损耗,建议最好在查询列表中只包含索引列,比如这个查询语句:

select key1,id from single_table where key1>'a' and key1<'c';

由于我们只查询key1列和id列的值,所以在使用idx_key1索引来扫描('a','c')区间中的二级索引时,可以直接从获取到的二级索引记录中读出key1列和id列的值,而不需要再通过id值到聚簇索引中执行回表操作了,这样就省去了回表操作带来的性能损耗。

我们把这种索引中已经包含了所有需要读取的列的查询方式称为覆盖索引。如果索引的叶子节点中已经包含要查询的数据,那么还有必要再回表查询呢?如果一个索引包含所有需要查询的字段的值,就称为覆盖索引。

排序操作也优先使用覆盖索引进行查询,比如下面这个查询语句:

select key1 from single_table order by key1;

虽然这个查询语句中没有limit子句,但是由于可以采用覆盖索引,所以查询优化器会直接使用idx_key1索引进行排序,而不需要执行回表操作。

当然,如果业务需要查询索引列以外的列,还是要以保证业务需求为重,如无必要,最好把业务中需要的列放在查询列表中,而不是以简单的*替代。

5、让索引列以列名的形式在搜索条件中单独出现

在下面这两个查询语句中,搜索条件中的语义是一样的:

select * from single_table where key2*2<4;
select * from single_table where key2<4/2;

在第一个查询语句的搜索条件中,key2列并不是以单独列名的形式出现的,而是以key2*2这样的形式表现的,mysql并不会尝试简化key2*2<4表达式,而是直接认为这个搜索条件不能形成合适的扫描区间来减少需要扫描的记录数量,所以该查询语句只能以全表扫描的方式来执行。

在第二个查询语句的搜索条件中,key2列并是以单独列名的形式出现的,Mysql可以分析出key2<2,这样可以减少需要扫描的记录数量。所以MySQL可能使用uk_key2来执行查询。

所以,如果想让某个查询使用索引来执行,请让索引列以列名的形式单独出现在搜索条件中。

6、新插入记录时主键大小对效率的影响

我们知道,对于一个使用InnoDB存储引擎的表来说,在没有显式创建索引时,表中的数据实际上存储在聚簇索引的叶子节点中,而且B+树的每一层数据页以及页面中的记录都是按照主键值从小到大的顺序排序的,如果新插入记录的主键值是依次递增的话,每插满一个数据页就换到下一个数据页继续插入,如果新插入记录的主键值忽大忽小,就比较麻烦了。

假设某个数据页存储的聚簇索引记录已经满了,它存储的主键值在1~100之间,此时如果再插入一提哦啊主键值为9的记录,因为这个数据页已经满了,新纪录应该插入到哪里呢?

我们需要把当前页面分裂成两个页面,把本页中的一些记录移动到新创建的一些页中,页分裂意味着性能损耗,所以如果想尽量避免这种无谓的性能损耗,最好让插入记录的主键值依次递增。即让主键拥有auto_increment属性,MySQl会自动为新插入的记录生成递增的主键值。

7、冗余和重复索引

针对single_table表,可以单独针对key_part1列建立一个idx_key_part1索引:

alert table single_table and index idx_key_part1(key_part1);

而此时我们已经有了一个针对key_part1、key_part2、key_part3列建立的联合索引idx_key_paridx_key_part索引的二级索引记录本身就是按照key_part1列的值排序的,此时再单独为key_part1列建立一个索引其实是没必要的,我们可以把整个新建的idx_key_part1索引看作一个冗余索引,该冗余索引是没有必要的。

有时,我们可能会对同一个列建立多个索引,比如下面两个添加索引的语句:

alert table single_table add unique key uk_id(id);
alert table single_table add index idx_id(id);

我们针对id列又建立了一个唯一二级索引uk_id,还建立了一个普通二级索引idx_id,可是id列本身就是single_table表的主键,InnoDB自动为该列建立了聚簇索引,此时uk_ididx_id就是重复的,这种重复索引应该避免。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!   

您可能感兴趣的文档:

--结束END--

本文标题: MySQL为数据表建立索引的原则详解

本文链接: https://www.lsjlt.com/news/141000.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL为数据表建立索引的原则详解
    目录1.索引是什么?2.索引的优点3.索引的缺点4.在建立索引的时候,都有哪些需要考虑的因素呢1、只为用于搜索、排序、分组的列创建索引2、索引列的类型尽量小3、为列前缀建立索引4、覆...
    99+
    2024-04-02
  • MySQL为数据表建立索引的原则是什么
    这篇文章给大家分享的是有关MySQL为数据表建立索引的原则是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。面试题:索引是什么?索引的优点?索引的缺点?在建立索引的时候都有哪些需要考虑的因素呢为数据表建立索引的...
    99+
    2023-06-29
  • mysql索引建立的原则是什么
    小编给大家分享一下mysql索引建立的原则是什么,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!尽量选择区分度高的列来建立索引。频繁查询列适合建立索引。遇到联合索引时,想想最左边的匹配原则。like模糊查询时,%在前面时才会...
    99+
    2023-06-25
  • MySQL索引建立的基本原则是什么
    MySQL索引建立的基本原则有以下几点: 索引应该建立在经常用于检索数据的列上,比如在WHERE子句、JOIN子句或OR...
    99+
    2024-03-13
    MySQL
  • 怎么使用navicat为数据库表建立索引?
    这篇文章将为大家详细讲解有关怎么使用navicat为数据库表建立索引,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。下面介绍如何使用Navicat为数据库表建立索引的具体操...
    99+
    2024-04-02
  • mysql建立索引的规则是什么
    建立索引的规则如下: 唯一性:索引列的值应该是唯一的,这样可以通过索引来确保数据的唯一性。 选择性:索引列的值应该具有高选择...
    99+
    2024-04-09
    mysql
  • python怎么建立mysql数据库索引
    使用python建立mysql数据库索引的方法创建主键索引方法一:create table biao (id int auto_increment primary key...
    99+
    2024-04-02
  • MYSQL中怎么建立数据库索引
    这篇文章给大家介绍MYSQL中怎么建立数据库索引,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 1、  通过创建唯一性索引,可以保证数据库表中每一 行数据的唯一性。...
    99+
    2024-04-02
  • mysql创建索引的原则有哪些
    创建索引的原则有以下几点:1. 选择合适的列:选择作为索引的列应该是经常用于查询和连接的列,而不是很少使用的列。2. 索引的选择性:...
    99+
    2023-09-21
    mysql
  • MySQL数据库索引的最左匹配原则
    目录一. 联合索引说明二. 那ac是否能用到索引呢?三. 思考四. 最左匹配原则的成因一. 联合索引说明 建立三个字段的联合索引 联合索引(a,b,c)相当于建立了索引:(a),(a...
    99+
    2024-04-02
  • 图文详解Mysql索引的最左前缀原则
    目录前言1. 定义2. 全索引顺序3. 部分索引顺序3.1 正序3.2 乱序4. 模糊索引5. 范围索引总结前言 之所以有这个最左前缀索引 归根结底是mysql的数据库结构 B+树 ...
    99+
    2024-04-02
  • 数据库建立索引的方法
    这篇文章主要介绍数据库建立索引的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!  索引用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,...
    99+
    2024-04-02
  • MySQL索引创建原则的示例分析
    小编给大家分享一下MySQL索引创建原则的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、适合创建索引1、字段的数值有唯一性限制根据Alibaba规范,...
    99+
    2023-06-29
  • MySQL数据库索引的设计原则是什么
    本篇内容主要讲解“MySQL数据库索引的设计原则是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL数据库索引的设计原则是什么”吧!为了使索引的使用效...
    99+
    2024-04-02
  • 如何在 ASP 中为数据类型建立索引?
    在ASP中为数据类型建立索引可以提高查询效率和数据的访问速度。本文将介绍如何在ASP中为数据类型建立索引。 一、什么是索引? 索引是一种数据结构,用于加快对数据的查询速度。索引可以理解为一本书的目录,它记录了每个关键词在书中出现的位置,方便...
    99+
    2023-07-30
    数据类型 索引 框架
  • MySQL组合索引与最左匹配原则详解
    前言 之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章,自以为就了解了其原理,最近面试时和面试官交流,发现遗漏了些东西,这里自己整理一下这方面的内容。 什么时候创建组合索引? 当我们...
    99+
    2024-04-02
  • 数据库索引的科学:设计有效索引的原则
    索引是数据库中至关重要的结构,通过优化数据访问来提高查询性能。有效地设计索引可以显著提升应用的响应时间和用户体验。 分 1. 确定高选择性列 索引列应具有较高的选择性,这意味着其值不同且分布均匀。选择性高的列可以快速缩小搜索范围,从而提高...
    99+
    2024-03-15
    数据库索引
  • MySQL数据库之索引详解
    目录一、MySQL索引简介二、MySQL五种类型索引详解(一)普通索引(二)唯一性索引(三)主键索引(四)复合索引(五)全文索引三、MySQL索引使用原则总结今天继续给大家介绍MyS...
    99+
    2024-04-02
  • MySQL创建数据表并建立主外键关系详解
    前言 为mysql数据表建立主外键需要注意以下几点: 需要建立主外键关系的两个表的存储引擎必须是InnoDB。 外键列和参照列必须具有相似的数据类型,即可以隐式转换的数据类型。 外键列和参照列...
    99+
    2024-04-02
  • MySQL数据库索引的最左匹配原则是什么
    这篇文章主要为大家展示了“MySQL数据库索引的最左匹配原则是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“MySQL数据库索引的最左匹配原则是什么”这篇文章吧。一. 联合索引说明建立三个字...
    99+
    2023-06-25
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作