有一个sql需要你去优化,那么你应该从什么地方入手呢?当然,是先格式化sql,让它看起来顺眼,最好能够达到让你一眼看过去,就能够明白,这个多达上千行的sql分几个层次,用了哪些技术。再去看sql中,涉及到的表有哪些?然后,再深入分析sql中的逻辑层次关系。你并不需要去弄明白,这个sql做了什么。因为最终的需求是,它能够快速得到结果。真的非常快速的那种,你懂的。
那么,我们首先要做的第一步,就是美化这个sql,让它看起来顺眼。PL/SQL Beautifier 这个功能是 PL/SQL 的TOOL选项中的一个美化sql语句的工具。我觉得很好用。一个完整的,没有语法错误的sql,可以用它美化,这样至少格式看起来很顺眼。反之,如果一个sql用它去美化,而没有起什么作用,那么说明sql中有语法错误。
其次,我们去找这个sql中有多少个表。我说的是实际的表,不是一个子查询构成的放在from后的虚表(在这里,我且将这样的表叫做虚表),而是from后面真正的表,它是一个表名。
我们将这些表摘出来,查看这些表的统计信息。优化器依赖统计信息生成执行计划,统计信息过时会导致性能问题。这是很重要的一步。如果统计信息都不准确,统计信息是十几天前的,甚至是几个月之前的,那么这个sql肯定是影响性能的。你不将统计信息收集为最新的,而去看索引、执行计划等都是没用的。索引这时候,也许也已经过期了,执行计划走偏,不是你想要让它走的。
当这个sql中,所有涉及到的表的统计信息是最新的,你再运行sql,发现运行效率明显提升,那么这个时候可以说,你的优化暂告一段落。因为在生产环境中,系统的稳定是第一的,非必要不去调整原有的其他配置。比如索引。
关于索引。索引的概念这里就不说了,要说的是,如何从这个sql中,在涉及到的表的索引中发现问题。这其中包括:索引未创建、索引重复创建、索引创建不合理、索引过旧、索引过期、索引失效等。
- 索引未创建,是指需要创建索引的字段,未创建索引。
- 索引重复创建,是指人工创建索引后,数据库有可能因为其他操作会自动创建有相同字段的组合索引。
- 索引创建不合理,是指某些小表体量小,不需要创建索引的;或某些字段创建复合索引比单独一个字段创建索引后查询效率高;或某些大表的索引在先前创建是合理的,但经过无数次的增删改查操作,使表中某些字段的数据分布变的不均衡了等,都有可能。
- 索引过旧/过期/失效:需要重新创建索引。
执行计划。一个高效的执行计划,是sql执行效率的保障。错误的执行计划,会导致极大的效率偏差。优化器根据收集的统计信息选择最优的执行计划。执行计划中,sql的执行顺序、语句之间的的依赖关系、索引,甚至更好的sql写法,都会影响到最终的查询效率。在这里不说执行计划如何分析,但是影响执行计划优劣的,归根结底,我个人认为有以下几点:
表数据量的大小,表数据量级直接影响全表扫描与索引扫描的成本评估,当数据量超过特定阀值时,优化器会重新评估权衡访问路径。
数据的质量,数据分布是否均衡、空值比例、重复值频率等,这些指标将决定索引选择的有效性和多表连接的合理性。数据分布是否均衡、数据存储的连续性会显著的降低I/O,并提升效率。
合理的索引,更好的多表关联。
现在,就这些吧!