提高数据库性能的SQL优化技术
1。减少IO数量
IO始终是本地数据库最容易的瓶颈,这是由数据库的责任决定的,超过90%的时间大部分数据库操作都是由IO操作占用的,减少IO的数量是SQL在优化过程中的首要任务,优化方法是最明显的效果。
2,减少CPU计算
除了IO瓶颈,CPU的运行优化需要在SQL优化考虑。排序,组,不同的…所有的大家庭,消耗CPU(这些操作基本上都是在CPU处理内存中的数据比较操作)。当我们的IO优化到一定阶段,减少CPU的计算将成为我们的SQL优化的重要目标
优化方法
1。更改SQL执行计划
在定义目标之后,我们需要确定实现我们目标的方法。对于SQL语句,实现这2个目标的方法只有一个,那就是改变SQL执行计划,让他尽量避免走弯路,我们需要通过各种快捷方式找到数据,以减少IO和CPU的数量,减少计算的目标。
常见的误解
1、计数(1)和计数(primary_key)优于计数(*)
许多人使用的计数(1)和计数(primary_key)而不是数量(*)以计数的记录数。他们认为这种性能更好,但这是一个错误。在某些情况下,这可能更糟,对数据库的计数(*)计数操作应该做一些特殊优化。
2、计数(列)和计数(*)是相同的
这种误解在许多高级工程师或DBA中是常见的,许多人会想当然地认为这一点。事实上,计数(列)和计数(*)是完全不同的操作,代表不同的含义。
计数(列)是在结果集中有多少列字段不是空的记录。
计数(*)是代表整个结果集的记录数。
3,从……选择a,b比较,从……选择A,B,C,你可以使数据库访问更少的数据。
这种误解主要存在于大量的开发人员中,主要原因是数据库的存储原理不太了解。
事实上,大多数关系型数据库中存储的行(列)模式和数据访问操作都是基于一个固定大小的IO单元(称为块或页),通常是4KB,8KB。大多数时候,许多行存储在每个IO单元,每一行是所有领域的线上商店(除特殊领域如LOB)。
因此,我们需要一个字段或多个字段,实际上数据库需要在表中访问的数据量实际上是相同的。
当然,也有例外情况,也就是说,我们的查询可以在索引中完成。也就是说,当我们只取A和B两个字段时,就不需要返回表。我们不需要在C中使用索引,而是需要返回表来获取数据。
4,按需排序需要排序操作
我们知道索引数据实际上是有序的,如果我们需要对一致的数据和索引进行排序,我们的查询由这个索引执行,那么数据库通常会省略排序操作,并返回数据,因为数据库数据已经满足了我们知道排序的需求。
事实上,使用索引对有排序需求的SQL进行优化是一种非常重要的优化方法。
扩展阅读:MySQL命令的实现分析,MySQL中基于组的基本实现原理,以及MySQL的基本实现原理。在这3篇文章中,尤其是第一篇文章中,有更深入的分析。
5、在执行计划filesort会整理磁盘文件
这不是一种误解,我们不能责怪我们,而是因为MySQL开发者使用的话。filesort是我们可以看到显示在列额外的当我们使用解释命令查看SQL执行计划的信息。
事实上,只要一条SQL语句需要整理,使用filesort将显示,这并不意味着会有一个文件排序操作。
延伸阅读:了解filesort在MySQL命令输出的解释,我在这里有一个比较详细的介绍
基本原则
1,几乎没有加入
MySQL的优势在于简单,但在某些方面它也是不利的。MySQL的优化器是高效的,但由于统计信息量有限,对优化器的工作过程的可能性更容易越轨。对于复杂的多表连接,另一方面,由于对其优化的局限性,而加入的努力是不够的,性能远远从Oracle关系数据库的前辈。但如果它是一个简单的单表查询,这一差距将是最小的甚至在某些情况下要优于这些数据库的前辈。
2,尽可能少
排序操作消耗更多的CPU资源,因此减少排序会导致较高的缓存命中率和IO能力,这将极大地影响SQL的响应时间。
对于MySQL,有很多方法可以减少排序,例如:
通过使用索引对它们进行排序,从而优化了上述误解。
减少参与订单中的条目数目
不必要的数据排序是不必要的。
…
三.尽量避免选择*。
许多人觉得很难理解这一点。不是在错误的地方。刚才,SELECT子句中有多少字段不影响读取的数据
是的,大部分时间都不会影响IO量,但是当我们也是按顺序操作时,SELECT子句中的列会对我们的排序效率产生很大的影响,这可以通过我以前的文章对MySQL命令实现的顺序进行分析,对文章进行详细的介绍。
此外,上述误解不是,但大部分时间不会影响IO量。当我们的查询结果只能在索引中找到时,它将大大减少IO量。
4。尝试替换子查询与连接
虽然加入性能不好,随着MySQL查询相比,它有一个非常大的性能优势。MySQL的子查询执行计划一直是个大问题。虽然这个问题已经存在很多年了,但在所有稳定的版本中已经普遍存在,而且没有得到很大的改善,虽然政府早就认识到了这个问题,并承诺尽快解决它,至少到目前为止,我们还没有看到哪个版本更好地解决了这个问题。
5,几乎等于或
当WHERE子句在存在多个条件或共存时,MySQL优化器并没有很好的解决方案优化问题,再加上MySQL特有的SQL和存储分层体系结构,性能比较低,很多时间都采用联合或全部(必要时)方式代替或将获得更好的效果。
6,试着用工会取代工会。
联盟与联盟之间的区别是,前者需要合并两个(或多个)的结果集,然后执行独特的过滤操作,这将涉及排序,增加大量的CPU运算,增加资源消耗和延迟。所以我们尝试使用联盟所有而不是工会的时候我们可以确认它是不可能重复的结果集或不愿意重复的结果集。
7。尽量尽可能早地过滤。
实际上,这种优化策略在索引的优化设计中最为常见(在字段前面放置了更好的过滤器)。
在SQL语句编写,这一原则也可以用来优化一些连接的SQL。例如,当我们查询多个表中的数据分页,我们应该在一个表上的数据过滤好的第一页,再好的结果页面的连接表的添加,可以为多尽可能减少不必要的IO操作,大大减少IO操作消耗时间。
8。避免类型转换
此处所描述的类型转换指的是当列字段的类型与WHERE子句中传入参数的类型不一致时发生的类型转换。
在column_name变换的变换函数
它可以直接导致MySQL(事实上,其他数据库也会有同样的问题),并且不能使用索引。如果要转换,就要转换传入参数。
从数据库本身转换
如果我们传递的数据类型和字段类型不相同,并且我们不进行任何类型的转换,MySQL可能对数据的类型转换操作可能不被存储引擎处理,因此它将无法使用由执行计划引起的索引。
9。优先优化SQL的高并发性,而不是执行一些大型的低频SQL。
对于破坏、高并发的SQL总是会比低频率,因为高并发的SQL甚至跨系统一旦有问题,也不会给我们任何喘息的机会。一些SQL,消耗了大量的IO和响应很慢,由于频率低,即使遇到,最主要的是要使整个系统反应慢,但至少有一段时间,让我们有缓冲的机会。
10。从全局优化,不是片面调整
SQL优化暂时无法分离,应该充分考虑所有的SQL系统,特别是当SQL通过调整索引优化计划时,不关心这一点而失去它,他。
11,尽可能多地解释数据库中运行的每一个SQL
为了优化SQL,我们需要对我们所知道的有一个概念。我们需要知道SQL以决定是否存在优化空间的执行计划,以确定是否有执行计划。一段数据库操作SQL优化后,明显的SQL可能很少有,大多需要探索,这时间对大量需要收集执行计划的说明操作,并确定是否需要优化。
通过IT168技术