zoukankan      html  css  js  c++  java
  • 来了解一下Mysql索引的相关知识:基础概念、性能影响、索引类型、创建原则、注意事项

    索引的基础概念
    索引类似于书籍的目录,要想找到一本书的某个特定主题,需要先查找书的目录,定位对应的页码;存储引擎使用类似的方式进行数据查询,先去索引当中找到对应的值,然后根据匹配的索引找到对应的数据行


    索引对性能的影响
    大大减少服务器需要扫描的数据量、帮助服务器避免排序和临时表、将随机I/O变成顺序I/O、大大提高查询速度,读写降低写的速度(读写操作会操作索引)并且占用磁盘开销(索引也是数据)


    索引的类型
    普通索引:最基本的索引,没有任何约束限制
    唯一索引:与普通索引类似,但是具有唯一性索引
    主键索引:特殊的唯一索引,不允许有空值
    唯一索引和主键索引的区别:一个表只能有一个主键索引,可以有多个唯一索引。主键索引一定是唯一索引,唯一索引不是主键索引。主键可以与外键构成参照完整性约束,防止数据不一致
    组合索引:将多个列组合在一起创建索引,可以覆盖多个列。(比如查询某本书的第几个小节,那么需要创建章和节的索引)
    外键索引:只有InnoDB类型的表才可以使用外键索引,保证数据的一致性、完整性和实现级联操作。
    全文索引:Mysql自带的全文索引只用于MyIsam,并且只能对英文全文检测


    Mysql索引的创建原则

    1:最适合索引的列是出现在WHERE子句中的列,或连接子句中的列而不是出现在SELECT关键字后的列(比如创建索引的时候,列是WHERE后的列,或者ON后的列)
    2:索引列的基数越大,效果越好
    3:对字符串进行索引,应该制定一个前缀长度,可以节省大量的索引空间,不然开销很大的空间
    4:根据情况创建复合索引,复合索引可以提高查询效率
    5:避免过多创建索引,索引会额外占用磁盘空间,降低写操作效率
    6:主键尽可能选择较短的数据类型,可以有效的减少索引的磁盘占用提高查询效率
    7:频繁更新增删改的字段表不要加索引
    8:查询中与其他表关联的字段,外间关系建立索引
    9:单键/组合索引的选择上,最好选择组合索引,特别是在高并发环境下
    10:查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
    11:查询中统计或者分组的字段(分组就是group by,但是分组的前提是必须排序,也就是分组和索引息息相关)
    12:表记录太少,不需要建索引,起码300W
    13:数据列包含需要重复的内容,不要建,比如性别


    Mysql索引的注意事项
    1:复合索引遵循前缀原则
    KEY(a,b,c),一个索引作用在abc三个字段上,比如书来说,章/节/段/
    有效的查询:/WEHRE a = 1 AND b = 2 AND c = 3/WHERE a = 1 AND b = 2 /WHERE a = 1
    无效的查询:/WHERE b = 2 AND c = 3/WHERE a = 1 AND c = 3
    原因:跳过a了,跳过了b,没有遵循前缀原则
    2:LIKE查询,%不能在前,可以使用全文检索解决
    如:WHERE name LIKE '%wang%',即使创建了索引也会失效。
    3:column is null 可以使用索引
    4:如果Mysql估计使用索引比全表扫描要慢,Mysql会放弃索引的使用
    如:表里有100条数据,语句为 WHERE id > 1 AND id <100,即使对id创建了索引,搜索的时候需要搜2~99的数据,搜索的时候回找id为2这条数据,先去索引看一下,找到位置,再去看数据行,再去看3,去看索引,再去看数据行....这样多了一个查询索引的步骤。但Mysql认为本身就100条, 你要查询98条数据,这样查就很慢了,我直接把100条扫一下直接返回了,比用索引快多了,自动放弃索引,因为Mysql本身具备优化器
    5:如果or前的条件中列有索引,后面的没有,索引都不会被用到
    如:WHERE a OR b ,a里有索引,b里没有,那么索引就会失效了
    6:列类型是字符串类型,查询时一定要给值加引号,否则索引失效
    如:WHERE name = 'wangteng',加引号才有效;再比如有时候字符串的列里有数字类型的字符,习惯性数字略掉引号,那么这样会失效

    以联合索引为例

      

    索引的一些场景

    1.选择唯一性索引
    唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话,可能存在同名现象,从而降低查询速度。
    2.为经常需要排序、分组和联合操作的字段建立索引
    经常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作会浪费很多时间。如果为其建立索引,可以有效地避免排序操作。
    3.为常作为查询条件的字段建立索引
    如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,为这样的字段建立索引,可以提高整个表的查询速度。
    4.限制索引的数目
    索引的数目不是越多越好。每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。
    5.尽量使用数据量少的索引
    如果索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索需要的时间肯定要比对CHAR(10)类型的字段需要的时间要多。
    6.尽量使用前缀来索引
    如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度
    7.删除不再使用或者很少使用的索引
    表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。
    8 . 最左前缀匹配原则,非常重要的原则。
    MySQL会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a 1=”” and=”” b=”2” c=”“> 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
    9 .=和in可以乱序。
    比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
    10 . 尽量选择区分度高的列作为索引。
    区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就 是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条 记录
    11 .索引列不能参与计算,保持列“干净”。
    比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本 太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);
    12 .尽量的扩展索引,不要新建索引。
    比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可
    注意:选择索引的最终目的是为了使查询的速度变快。上面给出的原则是最基本的准则,但不能拘泥于上面的准则。读者要在以后的学习和工作中进行不断的实践。根据应用的实际情况进行分析和判断,选择最合适的索引方式。

    索引优化口诀

    全值匹配我最爱,最左前缀要遵守;
    带头大哥不能死,中间兄弟不能断;
    索引列上少计算,范围之后全失效;
    LIKE百分写最右,覆盖索引不写星;
    不等空值还有OR,索引失效要少用;
    VARC引号不能丢,SQL高级也不难;

  • 相关阅读:
    linq——group by
    WebApi——json返回多了 k_BackingField
    Fiddler使用
    iis发布,部署
    项目梳理7——Nuget包管理
    CVS导出&&自定义Attribute的使用
    项目梳理6——使用WebApiTestClient为webapi添加测试
    项目梳理5——修改已生成.nuspec文件
    项目梳理4——WebApi项目,使用注释填充Description字段
    jQuery object and DOM Element
  • 原文地址:https://www.cnblogs.com/wt645631686/p/8193622.html
Copyright © 2011-2022 走看看