加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

深入浅出Mysql索引的那些事儿

发布时间:2019-08-23 01:24:37 所属栏目:编程 来源:猿人谷
导读:一.索引的作用 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重。 在数据量和访问量不大的情况下,mysql访问是非常快的

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

   3.索引列排序

mysql一张表查询只能用到一个索引。因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作,尽量不要包含多个列的排序,如果需要最好给这些列建复合索引。这一点是很多程序猿容易忽略的,如where子句的字段建了索引,排序的字段建了索引,但是分开建的,以为会走索引,其实这样的话排序的字段不会使用索引的,除非建复合索引,切记。

   4.like语句操作

一般情况下不鼓励使用like操作,如果非使用不可,注意正确的使用方式。like '%aaa%'不会使用索引,而like 'aaa%'可以使用索引。

  5.不要在列上进行运算

  6.不使用NOT IN 、<>、!=操作,但<,<=,=,>,>=,BETWEEN,IN是可以用到索引的。

  7.索引要建立在经常进行select操作的字段上。

这是因为,如果这些列很少用到,那么有无索引并不能明显改变查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。

  8.索引要建立在值比较唯一的字段上。

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

  10.在where和join中出现的列需要建立索引。

   11.where的查询条件里有不等号(where column != ...),mysql将无法使用索引。

   12.如果where字句的查询条件里使用了函数(如:where DAY(column)=...),mysql将无法使用索引。

   13.在join操作中(需要从多个数据表提取数据时),mysql只有在主键和外键的数据类型相同时才能使用索引,否则即使建立了索引也不会使用。这一点很容易忽略,切记,切记,切记!

   14.在进行联表查询时,建立关联的表的字段类型最好一样且长度一致,这样能更好的发挥索引的作用。

    15.组合索引时切记此条约束:组合索引中有多个字段,其中一个字段是有范围判断,则需将此字段在最后面。如

  1. ALTER TABLE USER_DEMO ADD INDEX name_age (NAME,AGE); 

因为age会有范围判断,则建组合索引时将AGE字段放在后面。

     16.字符集字段比较,UTF8与UTF-BIN联合查询是不能走索引的。

如某张表的order_no字段类型为varchar(50),另一张表的order_no字段类型为varchar(50) COLLATE utf8_BIN。则此时联合查询时不能走索引的,切记。

即两张表的字段类型如下:

  1. `order_no` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '订单号'; 
  2. `order_no` varchar(50) NOT NULL DEFAULT '' COMMENT '订单号'; 

     17.以下几种情况不适合建索引:

  • 表记录太少
  • 经常插入、删除、修改的表
  • 数据重复且分布平均的表字段。如一个表有10万行记录,其中字段column1只有A和B两种值,且每个值的分布概率大约为50%,那么对这种表column1字段建索引一般不会提高数据库的查询速度。

     18.给表创建主键,对于没有主键的表,在查询和索引定义上有一定的影响。

     19.避免表字段为null,建议设置默认值(如int类型设置默认值为0),这样在索引查询上,效率会高很多。

     20.关于order by的索引问题重点说下:

  • 无条件查询如果只有order by create_time,即便create_time上有索引,也不会使用到。

         因为优化器认为走二级索引再去回表成本比全表扫描排序更高,所以选择走权标扫描。

  • 无条件查询但是order by create_time limit m,如果m值较小,是可以走索引的。

         因为优化器认为根据索引有序性去回表查数据,然后得到m条数据,就可以终止循环,

         那么成本比全表扫描小,则选择走二级索引。

         即便没有二级索引,mysql针对order by limit也做了优化,采用堆排序。

  • order by排序分为file sort和index,index的效率更高。但以下情况不会使用index排序:
  1. 检查的行数过多,并且没有使用覆盖索引
  2. 使用了多个索引,mysql一次只会采用一个索引
  3. where和order by使用了不同的索引,与上一条类似
  4. order by中加入了非索引列,且非索引列不在where中
  5. 当使用left join,使用右边的表字段排序

【编辑推荐】

  1. 打破MySQL变慢瓶颈,是它们限制了MySQL性能
  2. 网络带宽如何影响 MySQL 性能
  3. MongoDB数据库误删后的恢复
  4. 删库不跑路-详解MySQL数据恢复
  5. 超详细的Oracle数据库索引创建及索引重建变更规范
【责任编辑:华轩 TEL:(010)68476606】
点赞 0

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读