Sql性能优化之索引

在做性能跟踪分析过程中,经常发现有不少后台程序的性能问题是因为缺少合适索引造成的,有些表甚至一个索引都没有。这种情况往往都是因为在设计表时,没去定义索引,而开发初期,由于表记录很少,索引创建与否,可能对性能没啥影响,开发人员因此也未多加重视。然一旦程序发布到生产环境,随着时间的推移,表记录越来越多
这时缺少索引,对性能的影响便会越来越大了。
这个问题需要数据库设计人员和开发人员共同关注
法则:不要在建立的索引的数据列上进行下列操作:

  • 避免对索引字段进行计算操作
  • 避免在索引字段上使用not,<>,!=
  • 避免在索引列上使用IS NULL和IS NOT NULL
  • 避免在索引列上出现数据类型转换
  • 避免在索引字段上使用函数
  • 避免建立索引的列中使用空值

索引:
转自:博文视点
索引是数据库优化所必需的工具,在面试的时候一般不会问概念性的问题,因为大家都能从教科书上找到答案,所以一般会问以下两方面的问题:

  ①索引有什么代价?哪些场景下你需要建索引?或者有时候反过来问,哪些场景下不推荐建索引。

  ②建好索引之后,怎么才能最高效地利用索引?或者反过来问,请说出一个无法有效利用已建索引的案例。

  从结构上来看,索引好比是一棵B树(也叫B*或者B+),假设学生表里只有学生ID和姓名两列,该学生表里有1000个学生,学号分别从1到1000,如果针对ID建立索引,大致的结构如下图所示。

这里写图片描述
  当然,在实际的数据库系统中,索引要比这个复杂得多,但从这个图里,我们能大致看出索引的工作原理。
索引建好后,如果我们要查找ID为111的学生,则数据库系统就会走索引,从图2.1中我们可以看到,根据根节点的指引,会找到第二层从左往右第二个数据块,以此类推,会在第四层里得到ID为111的物理地址,然后直接从硬盘里找数据。

  反过来,如果没有建索引,数据库系统可能就要从一个大的范围里逐一定位查找,效率就没这么高了。

  索引的好处大家已经看到了,那么为了得到这个“查询效率高”的好处,我们要付出了什么样的代价呢?

  1索引需要占硬盘空间,这是空间方面的代价。

  2一旦插入新的数据,就需要重新建索引,这是时间上的代价。

  关于索引性能问题,我会细问,你建索引的表规模多少?不少人直接告诉我表就几千条,我或者问,索引有什么代价?不少回答是索引是只有好处没坏处的,也就是说,可以随便建。

  对此我们来详细分析下(也就是大家在面试时需要说的):

  场景一,数据表规模不大,就几千行,即使不建索引,查询语句的返回时间也不长,这时建索引的意义就不大。当然,若就几千行,索引所占的空间也不多,所以这种情况下,顶多属于“性价比”不高。

  场景二,某个商品表里有几百万条商品信息,同时每天会在一个时间点,往其中更新大概十万条左右的商品信息,现在用where语句查询特定商品时(比如wherename=‘XXX’)速度很慢。为了提升查询效率可以建索引,但当每天更新数据时,又会重建索引,这是要耗费时间的。这时就需要综合考虑,甚至可以在更新前删除索引,更新后再重建。

  场景三,从上图中可以看到,因为在数据表里ID值都不相同,所以索引能发挥出比较大的作用。相反,如果某个字段重复率很高,如性别字段,或者某个字段大多数值是空(null),那么不建议对该字段建索引。

  请大家记住,一定是有业务需求了才会建索引。比如在一个商品表里,我们经常要根据name做查询,如果没有索引,查询速度会很慢,这时就需要建索引。但在项目开发中,如果不经常根据商品编号查询,那么就没必要对编号建索引。

  最后再强调一次,建索引是要付出代价的,没事别乱建着玩,同时在一个表上也不能建太多的索引。

  下面说下索引建好了该怎么用?毕竟大家花了不少时间和空间代价建了索引,至少得回本吧?

  如果出现一些不好的SQL语句,那么索引就白建了。下面通过一些具体的例子来看索引的正确用法。

  ①语句一:selectnamefrom商品表。不会用到索引,因为没有where语句。

  ②语句二:select*from商品表wherename=‘Java书’,会用到索引,如果项目里经常用到name来查询,且商品表的数据量很大,而name值的重复率又不高,那么建议建索引。

  ③语句三:select*from商品表wherenamelike‘Java%’这是个模糊查询,会用到索引,请大家记住,用like进行模糊查询时,如果第一个就是模糊的匹配符,比如wherenamelike‘%java’,那么在查询时不会走索引。在其他情况下,不论用了多少个%,也不论%的位置,只要不出现在第一个位置,那么都能用到索引。

  学生成绩表里有两个字段:姓名和成绩。现在对成绩这个整数类型的字段建索引。

  ①第一种情况,当数字型字段遇到非等值操作符时,无法用到索引。比如:
selectnamefrom学生成绩表where成绩>95,一旦出现大于符号,就不能用到索引,为了用到索引,我们应该改一下SQL语句里的where从句:where成绩in(96,97,98,99,100)

  ②第二种情况,如果对索引字段进行了某种左值操作,那么无法用到索引。

  能用到索引的写法:selectnamefrom学生成绩表where成绩=60

  不能用到索引的写法:selectnamefrom学生成绩表where成绩+40=100

  ③第三种情况,如果对索引字段进行了函数操作,那么无法用到索引。

  比如SQL语句:select*from商品表wheresubstr(name)=‘J’,我们希望查询商品名首字母是J的记录,可一旦针对name使用函数,即使name字段上有索引,也无法用到。

  关于索引,当然还有位图索引和复合索引等,如果大家要应聘更高级的岗位(比如有5年经验了),那么就不能止步于此了,但根据我的面试经验,上述关于索引的说辞对工作经验3年以下的候选人是有帮助的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL优化中使用索引是一种常见的方法。索引可以加快数据库的查询速度和性能。下面是一些使用索引进行SQL优化的常见技巧: 1. 选择合适的列进行索引:通常情况下,需要在经常用于查询条件的列上创建索引。选择经常用于筛选、排序或连接操作的列可以提高查询性能。 2. 避免过多的索引:虽然索引可以提高查询速度,但过多的索引会增加数据库的维护成本并降低写入性能。只创建必要的索引,避免不必要的列进行索引。 3. 多列索引优化:对于经常一起使用的列,可以创建多列索引以提高查询性能。多列索引可以更好地满足复杂查询条件。 4. 聚簇索引优化:聚簇索引是一种特殊的索引类型,它可以将数据物理上组织在一起。通过合理地选择聚簇索引,可以减少磁盘IO和提高查询性能。 5. 使用覆盖索引:覆盖索引是指索引包含了查询所需的所有列。通过使用覆盖索引,可以减少数据库的访问次数,从而提高查询性能。 6. 定期更新统计信息:统计信息用于查询优化器选择合适的索引和执行计划。定期更新统计信息可以确保查询优化器能够做出更准确的选择,提高查询性能。 7. 避免索引过度优化:有候过度使用索引可能会导致性能下降。当数据量较小或查询频率低,可以考虑不使用索引或者使用覆盖索引来避免过度优化带来的性能问题。 需要注意的是,索引的创建和维护会增加额外的开销,因此在使用索引进行优化需要综合考虑查询频率、数据量和维护成本等因素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值