很多数据库系统性能不理想是因为系统没有经过整体优化,存在大量性能低下的SQL 语句。这类SQL语句性能不好的首要原因是缺乏高效的索引。没有索引除了导致语句本身运行速度慢外,更是导致大量的磁盘读写操作,使得整个系统性能都受之影响而变差。

解决这类系统的首要办法是优化这些没有索引或索引不够好的SQL语句。
1.创建索引的关键
优化SQL语句的关键是尽可能减少语句的logical reads。这里说的logical reads是指语句执行时需要访问的单位为8K的数据页总数。logical reads 越少,其需要的内存和CPU时间也就越少,语句执行速度就越快。不言而喻,索引的最大好处是它可以极大减少SQL语句的logical reads数目,从而极大减少语句的执行时间。创建索引的关键是索引要能够大大减少语句的logical reads。一个索引好不好,主要看它减少的logical reads多不多。运行set statistics io命令可以得到SQL语句的logical reads信息。
set statistics io on
select au_id,au_lname ,au_fname
from pubs..authors where au_lname ='Green'
set statistics io on
如果Logical reads很大,而返回的行数很少,也即两者相差较大,那么往往意味者语句需要优化。Logical reads中包含该语句从内存数据缓冲区中访问的页数和从物理磁盘读取的页数。而physical reads表示那些没有驻留在内存缓冲区中需要从磁盘读取的数据页。Read-ahead reads是SQL Server为了提高性能而产生的预读。预读可能会多读取一些数据。 优化的时候我们主要关注Logical Reads就可以了。注意如果physical Reads或Read-ahead reads很大,那么往往意味着语句的执行时间(duration)里面会有一部分耗费在等待物理磁盘IO上。
2.单字段索引,组合索引和覆盖索引

单字段索引是指只有一个字段的索引,而组合索引指有多个字段构成的索引。
(1) 对出现在where子句中的字段加索引
set statistics profile on
set statistics io on
go
select .... from tb where ...
go
set statistics profile off
set statistics io off
set statistics profile命令将输出语句的执行计划。
也许你会问,为什么不用SET SHOWPLAN_ALL呢?使用SET SHOWPLAN_ALL也是可以的。不过set statistics profile输出的是SQL 语句的运行时候真正使用的执行计划,而SET SHOWPLAN_ALL输出的是预计(Estimate)的执行计划。使用SET SHOWPLAN_ALL是后面的语句并不会真正运行。用了Table Scan,也就是对整个表进行了全表扫描。全表扫描的性能通常是很差的,要尽量避免。如果上面的select语句是数据库系统经常运行的关键语句, 那么应该对它创建相应的索引。创建索引的技巧之一是对经常出现在where条件中的字段创建索引Table Scan也变成了Index Seek,性能极大提高,设法避免Table scan或Index scan是优化SQL 语句使用的常用技巧。通常Index Seek需要的logical reads比前两者要少得多。

(2).组合索引
如果where语句中有多个字段,那么可以考虑创建组合索引。组合索引中字段的顺序是非常重要的,越是唯一的字段越是要靠前。另外,无论是组合索引还是单个列的索引,尽量不要选择那些唯一性很低的字段。比如说,在只有两个值0和1的字段上建立索引没有多大意义。
所以如果对单字段进行索引,建议使用set statistics profile来验证索引确实被充分使用。logical reads越少的索引越好。
(3).覆盖索引
覆盖索引能够使得语句不需要访问表仅仅访问索引就能够得到所有需要的数据。因为聚集索引叶子节点就是数据所以无所谓覆盖与否,所以覆盖索引主要是针对非聚集索引而言。执行计划中除了index seek外,还有一个Bookmark Lookup关键字。 Bookmark Lookup表示语句在访问索引后还需要对表进行额外的Bookmark Lookup操作才能得到数据。也就是说为得到一行数据起码有两次IO,一次访问索引,一次访问基本表。如果语句返回的行数很多,那么Bookmark Lookup操作的开销是很大的。覆盖索引能够避免昂贵的Bookmark Lookup操作,减少IO的次数,提高语句的性能。覆盖索引需要包含select子句和WHERE子句中出现的所有字段。Where语句中的字段在前面,select中的在后面。logical reads,是大大减少了。Bookmark Lookup操作也消失了。所以创建覆盖索引是减少logical reads提升语句性能的非常有用的优化技巧。
实际上索引的创建原则是比较复杂的。有时候你无法在索引中包含了Where子句中所有的字段。在考虑索引是否应该包含一个字段时,应考虑该字段在语句中的作用。比如说如果经常以某个字段作为where条件作精确匹配返回很少的行,那么就绝对值得为这个字段建立索引。再比如说,对那些非常唯一的字段如主键和外键,经常出现在group by,order by中的字段等等都值得创建索引。
问题1,是否值得在identity字段上建立聚集索引。
答案取决于identity 字段如何在语句中使用。如果你经常根据该字段搜索返回很少的行,那么在其上建立索引是值得的。反之如果identity字段根本很少在语句中使用,那么就不应该对其建立任何索引。
问题2,一个表应该建立多少索引合适。
如果表的80%以上的语句都是读操作,那么索引可以多些。但是不要太多。特别是不要对那些更新频繁的表其建立很多的索引。很少表有超过5个以上的索引。过多的索引不但增加其占用的磁盘空间,也增加了SQL Server 维护索引的开销。
问题3:为什么SQL Server 在执行计划中没有使用你认为应该使用的索引?

原因是多样的。一种原因是该语句返回的结果超过了表的20%数据,使得SQL Server 认为scan比seek更有效。另一种原因可能是表字段的statistics过期了,不能准确反映数据的分布情况。
你可以使用命令UPDATE STATISTICS tablename with FULLSCAN来更新它。只有同步的准确的statistics才能保证SQL Server 产生正确的执行计划。过时的老的statistics常会导致SQL Server生成不够优化的甚至愚蠢的执行计划。所以如果你的表频繁更新,而你又觉得和之相关的SQL语句运行缓慢,不妨试试UPDATE STATISTIC with FULLSCAN 语句。
问题4、什么使用聚集索引,什么时候使用非聚集索引
在SQL Server 中索引有聚集索引和非聚集索引两种。它们的主要差别是前者的索引叶子就是数据本身,而后者的叶子节点包含的是指向数据的书签(即数据行号或聚集索引的key)。

对一个表而言聚集索引只能有一个,而非聚集索引可以有多个。只是聚集索引没有Bookmark Lookup操作。什么时候应该使用聚集索引?  什么时候使用非聚集索引? 取决于应用程序的访问模式。我的建议是在那些关键的字段上使用聚集索引。一个表一般都需要建立一个聚集索引。
对于什么时候使用聚集索引,SQL Server 2000联机手册中有如下描述:
在创建聚集索引之前,应先了解您的数据是如何被访问的。可考虑将聚集索引用于:

包含大量非重复值的列;

使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。被连续访问的列;
返回大型结果集的查询;
经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。
对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。OLTP 类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。
聚集索引不适用于:

频繁更改的列:这将导致整行移动(因为 SQL Server 必须按物理顺序保留行中的数据值)。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的。

宽键:来自聚集索引的键值由所有非聚集索引作为查找键使用,因此存储在每个非聚集索引的叶条目内。

转载于:https://www.cnblogs.com/yepei/p/5649293.html

MySQL之索引优化相关推荐

  1. 知识点:Mysql 数据库索引优化实战(4)

    知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 一:插入订单 业务逻辑:插 ...

  2. Mysql之索引优化案例

    Mysql之索引优化案例 1.单表简单案例 1.1创建表 1.2 问题: 1.3 解决:新建索引 1.4 再次执行 2.双表简单案例 2.1创建表并插入数据 2.2 由于是LEFT JOIN,所以左表 ...

  3. MySQL - 践行索引优化

    文章目录 生猛干货 Pre Table Demo DB Version Case 全值匹配 最左前缀 禁止索引列上做任何操作(计算.函数.(自动or手动)类型转换) 存储引擎不能使用索引中范围条件右边 ...

  4. mysql 字符串索引 优化_MySQL性能优化之索引调优实战

    索引失效场景或使用注意事项 a.索引无法存储null值,所以建议都给默认值 b.如果条件中有or,即使使用了索引条件也不起作用,所以尽量少用or 如果想使用or,又让索引生效,只能将or的每个列上加上 ...

  5. MySQL日记——索引优化

    索引优化最简单的一个法则 左连接建在右表,右连接建在左表 例如 select * from book left join category on category.class=book.class 这 ...

  6. Mysql高级 索引优化

    Mysql逻辑架构 Mysql与其他数据库相比有点与众不同,他的架构可以在多种不同的场景中应用并发挥作用,主要体现在存储引擎的架构上,插件式的存储引擎结构将查询处理和其他的系统任务以及数据的存储提取分 ...

  7. mysql复合索引优化

    很多时候,我们在mysql中创建了索引,但是某些查询还是很慢,根本就没有使用到索引! 一般来说,可能是某些字段没有创建索引,或者是组合索引中字段的顺序与查询语句中字段的顺序不符. 看下面的例子: 假设 ...

  8. MySQL:索引优化、查询优化

    一.哪些情况适合创建索引 1.字段的数值有唯一性的限制: 业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引: 说明:创建唯一索引会影响添加的速度(在添加的时候会维护索引),但是这个速度影响 ...

  9. MySQL高级-索引优化(超详细)

    性能分析 MySQL Query Optimizer Mysql中由专门负责优化SELECT语句的优化器,主要功能就是通过计算分析系统中收集到的统计信息,为客户端请求的Query提供他认为最优的执行计 ...

  10. 【MySQL】索引优化中的最左前缀原则和索引下推

    目录 一.引入 二.覆盖索引 ​ 讲接下来的问题前首先讲一下联合索引的底层存储结构长什么样?联合索引的检索过程是什么样的呢? 三.最左前缀原则 最左前缀原则的定义 四.索引下推 五.小结 一.引入 在 ...

最新文章

  1. 2021年春季学期-信号与系统-第七次作业参考答案-第四小题
  2. Hibernate关联关系映射实例速查
  3. 剑指Offer #04 重建二叉树(递归)
  4. 线性代数之矩阵偏导续
  5. linux 串口格式化输出字符串,如何把电压这个浮点值转字符串输出到串口
  6. SVN版本管理trunk及branch相关merge操作
  7. 如何用AnySDK快速接入SDK上线
  8. IEDevToolBar - 一个分析网页的有用的工具
  9. 中国电信:预计2021年归母净利润同比增长23%-25%
  10. C盘扩容_解决过程记录
  11. matlab画回归曲线方程,MATLAB线性回归方程与非线性回归方程的相关计算
  12. matlab设计计算器,MATLAB-计算器的设计.doc
  13. gpasswd命令简介
  14. 关于烛光斧影——赵光义是否谋杀赵匡胤,是否合法继位
  15. String metric
  16. 英语学习-索贝斯演讲学习摘要
  17. Indian English(印度英语)
  18. RPG游戏制作-07-特效层的创建
  19. 艾棣维欣联合INOVIO开展新冠DNA疫苗全球III期临床试验;陆道培医疗与辉瑞达成合作 | 医药健闻...
  20. [量化-007]为什么股市会存在

热门文章

  1. 怎样查询人工智能的前沿论文?
  2. opencv机器学习ml模块简介
  3. 7-1 两个有序链表序列的合并 (15 分)
  4. 数据结构栈之火车出站小结
  5. 深入浅出MySQL数据库(一)
  6. pytorch实现dcgan_PyTorch版本DCGAN实现的注解
  7. java虚拟机教程图解_深入拆解JAVA虚拟机学习教程
  8. Luogu P4774 / LOJ2721 【[NOI2018]屠龙勇士】
  9. Linux中ls -l(ll)返回结果中的文件访问权限-rw-r--rw-
  10. BZOJ 2648 SJY摆棋子(KD-Tree)