zoukankan      html  css  js  c++  java
  • 数据存储-1、MySQL 索引使用的注意事项

    索引的优点

    • 大大加快数据的查询速度
    • 使用分组和排序进行数据查询时,可以显著减少查询时分组和排序的时间
    • 创建唯一索引,能够保证数据库表中每一行数据的唯一性
    • 在实现数据的参考完整性方面,可以加速表和表之间的连接

    索引的缺点

    • 创建索引和维护索引需要消耗时间,并且随着数据量的增加,时间也会增加
    • 索引需要占据磁盘空间
    • 对数据表中的数据进行增加,修改,删除时,索引也要动态的维护,降低了维护的速度

    注意事项:

    1.WHERE字句的查询条件里有 NOT IN 、<>、!=,MYSQL将无法使用索引;

    2.WHERE字句的查询条件里使用了函数,MYSQL将无法使用索引

    3.在JOIN操作中,MYSQL只有在主键和外键的数据类型相同时才能使用索引,否则即使建立了索引也不会使用

    4.使用了比较操作符LIKE和REGEXP,MYSQL只有在搜索模板的第一个字符不是通配符的情况下才能使用索引。比如说,如果查询条件是LIKE 'abc%',MYSQL将使用索引;如果条件是LIKE '%abc'或者'_abc%',MYSQL将不使用索引。

    5.在ORDER BY操作中,MYSQL只有在排序条件不是一个查询条件表达式的情况下才使用索引。尽管如此,在涉及多个数据表的查询里,即使有索引可用,那些索引在加快ORDER BY操作方面也没什么作用。

    使用order by特别提示:
    1>mysql一次查询只能使用一个索引。如果要对多个字段使用索引,建立复合索引。
    2>在ORDER BY操作中,MySQL只有在排序条件不是一个查询条件表达式的情况下才使用索引。

    6.如果某个数据列里包含着许多重复的值,就算为它建立了索引也不会有很好的效果。比如说,如果某个数据列里包含了净是些诸如“0/1”或“Y/N”等值,就没有必要为它创建一个索引。

    7.使用短索引: 对串列进行索引,如果可以就应该指定一个前缀长度。例如,如果有一个char(255)的列,如果在前10个或20个字符内,多数值是唯一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。(针对hash的索引方式,对每个值都做hash值存储I/O操作存储索引信息)

    8.如果条件中有or(并且其中有or的条件是不带索引的),即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)。注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引

    9.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引

    10.对于那些定义为text、image和bit数据类型的列不应该增加索引。因为这些列的数据量要么相当大,要么取值很少。

    11.只要列中包含有NULL值,都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此符合索引就是无效的。

    12.组合索引之最左前缀:顾名思义,就是最左优先,上例中我们创建了name_age_course多列索引,相当于创建了(name)单列索引,(name,age)组合索引以及(name,age,course)组合索引。在单独使用(age)、(age,course)等条件下索引无效

    创建索引的原则

    • 更新频繁的列不应设置索引
    • 数据量小的表不要使用索引(毕竟总共2页的文档,还要目录吗?)
    • 重复数据多的字段不应设为索引(比如性别,只有男和女,一般来说:重复的数据超过百分之15就不该建索引)
    • 首先应该考虑对where 和 order by 涉及的列上建立索引

    补充:确认索引是否已使用:explain select username from user where id=1

    结果为:

    字段说明:

    • select_type  simple表示简单查询 还有其他如primary,union,subquery等
    • table  表名
    • partitions  匹配的分区
    • type  引擎在表中找到所需行的方式 由差到好为:all(全表扫描),index(只遍历索引树),range(索引范围扫描,常见于between,>,< 等查询中),ref(非唯一性索引扫描),eq_ref(唯一性索引扫描),const / system(当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问),null(MySQL在优化过程中分解语句,执行时甚至不用访问表或索引)
    • possible_keys  可供选择的索引
    • key  使用的索引
    • key_len  索引字节数的长度,数值越小,运行速度越快
    • ref  连接匹配条件,即哪些列或常量被用于查找索引列上的值
    • rows  返回的数据行数
    • filtered  被表条件过滤的行数的百分比
    • extra  额外信息  类型: using index(表示select操作中使用了覆盖索引),using where(mysql服务器在存储引擎受到记录后进行“后过滤“),using temporary(表示mysql需要使用临时表来存储结果集,常见于排序和分组查询), using filesort(mysql中无法使用索引完成的排序操作,成为“文件排序”)

    注意: 通过key就能判断索引是否执行

    优化mysql查询语句

    • 不要在where条件语句 '=' 的左边进行函数,运算符或表达式的计算,如 select name from tb_user where age/2=20,因为索引不会生效(引擎会放弃使用索引,进行全表扫描)
    • 不要使用 <>,!=,not in ,因为索引不会生效
    • 避免对字段进行null的判断,因为索引不会生效(可以用一个值代替null,如-999)
    • 使用like模糊查询时,like '%xx%'会导致索引不生效,like 'xx%' 索引能够被使用,所以避免使用第一种
    • 避免使用or,可以用union替代(要想使用or,又让索引生效,or条件中的每个列都必须加上索引)
    • 使用exist代替in(表中数据越多,exist的效率就比in要越大)
    • 数据类型隐形转换,索引不会生效:如 select name from user where phone=13155667788;(phone字段在数据库中为varchar类型,应改成 phone='13155667788')
    • 联合索引必须要按照顺序才会生效:如创建的索引顺序为a,b,where a="xx" and b="xx" 生效,但 b="xx" and a="xx" 则不会生效,补充:a="xx" 没有后面的,索引也会生效
    • 尽量避免使用游标(游标效率低)
    • 不要使用 select * 
    • 还有很多...

     

  • 相关阅读:
    第12组 Beta冲刺(2/5)
    第12组 Beta冲刺(1/5)
    第12组 Alpha事后诸葛亮
    第12组 Alpha冲刺(6/6)
    第12组 Alpha冲刺(5/6)
    第12组 Alpha冲刺(4/6)
    第12组 Alpha冲刺(3/6)
    第12组 Alpha冲刺(2/6)
    Why I start blogging.
    第二十章 更新和删除数据
  • 原文地址:https://www.cnblogs.com/chenxiaoxian/p/10426508.html
Copyright © 2011-2022 走看看