我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MySQL为数据表建立索引的原则是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MySQL为数据表建立索引的原则是什么

这篇文章给大家分享的是有关MySQL为数据表建立索引的原则是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

    面试题:

    • 索引是什么?

    • 索引的优点?

    • 索引的缺点?

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

    • 为数据表建立索引的原则有哪些?

    • 什么是索引覆盖?

    • 非聚簇索引一定会回表查询吗?

    1. 索引是什么?

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

    定位到记录所在的页

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

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

    2. 索引的优点?

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

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

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

    索引可以将随机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就是重复的,这种重复索引应该避免。

    感谢各位的阅读!关于“MySQL为数据表建立索引的原则是什么”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    MySQL为数据表建立索引的原则是什么

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

    下载Word文档

    猜你喜欢

    MySQL为数据表建立索引的原则是什么

    这篇文章给大家分享的是有关MySQL为数据表建立索引的原则是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。面试题:索引是什么?索引的优点?索引的缺点?在建立索引的时候都有哪些需要考虑的因素呢?为数据表建立索引
    2023-06-29

    mysql索引建立的原则是什么

    小编给大家分享一下mysql索引建立的原则是什么,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、尽量选择区分度高的列来建立索引。2、频繁查询列适合建立索引。3、遇到联合索引时,想想最左边的匹配原则。4、like模糊查询时
    2023-06-25

    MySQL索引建立的基本原则是什么

    MySQL索引建立的基本原则有以下几点:索引应该建立在经常用于检索数据的列上,比如在WHERE子句、JOIN子句或ORDER BY子句中经常用到的列上建立索引。索引应该选择性高,即不同的值较为均匀地分布在索引列中,这样可以更快地定位到所需的
    MySQL索引建立的基本原则是什么
    2024-03-13

    mysql建立索引的规则是什么

    建立索引的规则如下:唯一性:索引列的值应该是唯一的,这样可以通过索引来确保数据的唯一性。选择性:索引列的值应该具有高选择性,即不同值的数量越多越好。选择性越高,索引的效果就越好。长度:索引列的长度应该尽可能小,这样可以减少索引占用的存储空间
    mysql建立索引的规则是什么
    2024-04-09

    MySQL索引创建原则是什么

    本篇内容介绍了“MySQL索引创建原则是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、适合创建索引1、
    2023-05-25

    oracle索引创建的原则是什么

    创建索引的原则是根据查询的频率、数据的选择性和查询性能来决定。以下是创建索引的一些原则:频繁使用的查询应该创建索引:如果某个查询经常被执行,那么为该查询的列创建索引可以提高查询性能。数据的选择性高的列应该创建索引:选择性是指列中不同值的数量
    oracle索引创建的原则是什么
    2024-04-09

    MySQL数据库索引的最左匹配原则是什么

    这篇文章主要为大家展示了“MySQL数据库索引的最左匹配原则是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“MySQL数据库索引的最左匹配原则是什么”这篇文章吧。一. 联合索引说明建立三个字
    2023-06-25

    mysql索引优化的原则是什么

    MySQL索引优化的原则包括以下几点:选择合适的索引类型:MySQL支持多种索引类型,包括B-Tree索引、哈希索引和全文索引等。根据查询的特点和数据的特性选择合适的索引类型。选择合适的索引列:选择经常被查询的列作为索引列,可以加快查询的速
    mysql索引优化的原则是什么
    2023-10-28

    mysql建立索引的方法是什么

    这篇文章主要介绍了mysql建立索引的方法是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(
    2023-06-15

    mysql中索引的最左原则是什么

    今天就跟大家聊聊有关mysql中索引的最左原则是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、MySQL不会使用索引的情况:非独立的列独立的列是指索引列不能是表达式的一部分,
    2023-06-15

    Mysql索引的最左前缀原则是什么

    这篇文章主要介绍了Mysql索引的最左前缀原则是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Mysql索引的最左前缀原则是什么文章都会有所收获,下面我们一起来看看吧。前言之所以有这个最左前缀索引归根结底是
    2023-06-29

    mysql联合索引生效的原则是什么

    MySQL联合索引生效的原则是遵循最左前缀原则。也就是说,联合索引在查询时,只有按照索引的最左边的列开始查询时,索引才会生效。如果不按照最左边的列开始查询,那么索引将不会被使用。例如,对于一个联合索引 (col1, col2, col3)
    2023-10-27

    编程热搜

    目录