查询优化
查询优化是许多关系数据库管理系统和其他数据库(例如NOSQL和Graph数据库)的功能。查询优化器试图通过考虑可能的查询计划来确定执行给定查询的最有效方法。
通常,用户无法直接访问查询优化器:一旦查询将其提交到数据库服务器,并由解析器解析,然后将其传递到进行优化的查询优化器。但是,某些数据库引擎允许使用提示引导查询优化器。
查询是来自数据库的信息请求。它可以很简单,就像“找到一个社会保险号123-45-6789的人的地址”,或更复杂的人,例如找到30至39岁之间加利福尼亚州所有受雇已婚男子的平均工资比他们的配偶。”查询的结果是通过以数据库中的方式处理所需信息的方式来生成的。由于数据库结构很复杂,在大多数情况下,尤其是对于不太简单的查询,因此可以通过以不同的方式通过不同的数据结构和不同的订单从数据库中收集查询所需的查询数据。每种不同的方式通常需要不同的处理时间。相同查询的处理时间可能具有较大的差异,这取决于所选方法的一秒钟到几个小时。查询优化的目的是一个自动化过程,是找到在最短时间内处理给定查询的方法。时间上的巨大差异证明了执行查询优化的合理性,尽管找到确切的最佳查询计划(除所有可能性)通常非常复杂,本身耗时,但可能太昂贵了,而且通常是不可能的。因此,查询优化通常会通过比较几种常识性替代方案来在合理的时间内提供“足够好”的计划来近似最佳,而“足够好”的计划通常不会偏离最佳可能的结果。
一般考虑
在弄清楚最佳查询计划和选择质量的花费之间的时间之间是一个权衡的;优化器可能不会自行选择最佳答案。数据库管理系统的不同质量具有不同的方式来平衡这两个。基于成本的查询优化器评估各种查询计划的资源足迹,并将其用作计划选择的基础。这些为每个可能的查询计划分配了估计的“成本”,并以最小的成本选择计划。成本用于根据所需的I/O操作数量, CPU路径长度,磁盘缓冲空间的数量,磁盘存储服务时间以及并行性和其他平行单位之间的互连用法来估算评估查询的运行时成本根据数据字典确定的因素。检查的一组查询计划是通过检查可能的访问路径(例如,主索引访问,辅助索引访问,完整文件扫描)和各种关系表加入技术(例如, Merge Join ,Join, Hash Join ,product join)来形成。根据SQL查询的复杂性,搜索空间可能会变得很大。优化有两种类型。这些包括逻辑优化(生成一个关系代数来求解查询)和物理优化的序列,该序列用于确定执行每个操作的手段。
执行
大多数查询优化器表示查询计划是“计划节点”的树。计划节点封装执行查询所需的单个操作。节点被排列为树,其中中间结果从树的底部流到顶部。每个节点的子节点为零或更多的子节点 - 这些节点是输入输入到父节点的节点。例如,一个联接节点将具有两个子节点,这些节点代表两个联接操作数,而排序节点将具有单个子节点(要排序的输入)。树的叶子是通过扫描磁盘来产生结果的节点,例如通过执行索引扫描或顺序扫描。
加入订购
查询计划的性能在很大程度上取决于表格的顺序。例如,当加入3个表A,B,C的大小10行,10,000行和1,000,000行时,与B和C首先加入B和C的查询计划可以花几个时间命令的时间来执行多个时间,而不是一个比以上的时间。首先加入A和C。大多数查询优化器通过IBM系统R数据库项目率先使用的动态编程算法确定加入顺序。该算法在两个阶段起作用:
- 首先,计算所有访问查询中每个关系的方法。查询中的每个关系都可以通过连续扫描访问。如果在关系上有一个索引,可以用来回答查询中的谓词,则也可以使用索引扫描。对于每个关系,优化器都会记录扫描关系的最便宜方法,以及扫描以特定排序顺序产生记录的关系的最便宜的方法。
- 然后,优化器考虑结合存在联接条件的每对关系。对于每对,优化器将考虑DBMS实现的可用联接算法。除了加入根据特定排序订单产生其产出的每对关系的最便宜的方式外,它还将保留加入每对关系的最便宜方法。
- 然后,通过将上一个阶段产生的每个两关系计划与查询中的剩余关系联系在一起,可以计算所有三关系查询计划。
排序顺序可以避免在处理查询时以后进行冗余排序操作。其次,特定的排序顺序可以加快后续加入,因为它以特定的方式将数据群簇簇。
嵌套SQL查询的查询计划
对现代关系DBMS的SQL查询不仅仅是选择和加入。特别是,SQL查询通常通过组的组嵌套几层SPJ块(选择项目 - 加入),而不是存在运营商。在某些情况下,这些嵌套的SQL查询可以将其扁平化成精选的项目加入查询,但并非总是如此。还可以使用与加入顺序的相同动态编程算法选择嵌套SQL查询的查询计划,但这可能会导致查询优化时间的巨大升级。因此,某些数据库管理系统使用使用查询图模型的替代基于规则的方法。
费用估算
查询优化中最困难的问题之一是准确估计替代查询计划的成本。优化者使用查询执行成本的数学模型成本查询计划,该模型在很大程度上取决于在查询计划中流过每个边缘的基数或单元数量的估计。基数估计反过来取决于查询中谓词的选择因子的估计值。传统上,数据库系统通过有关每列中值分布(例如直方图)的详细统计数据来估计选择性。该技术可很好地估计单个谓词的选择性。但是,许多查询都具有谓词(例如select count ( * ) from R where R . make = 'Honda' and R . model = 'Accord'
的结合select count ( * ) from R where R . make = 'Honda' and R . model = 'Accord'
。查询谓词通常是高度相关的(例如, model='Accord'
意味着make='Honda'
),并且很难估计相结合的选择性。较差的基数估计和未被发现的相关性是查询优化者选择不良查询计划的主要原因之一。这就是数据库管理员应定期更新数据库统计信息的原因之一,尤其是在主要数据加载/卸载之后。
扩展
经典查询优化假定根据一个单一成本度量(通常是执行时间)比较查询计划,并且可以在不确定性的情况下计算每个查询计划的成本。在实践中有时会违反这两个假设,并且在克服这些局限性的研究文献中已经研究了经典查询优化的多个扩展。这些扩展的问题变体在对单个查询计划的成本和优化目标方面的建模方式上有所不同。
参数查询优化
经典查询优化将每个查询计划与一个标量成本值相关联。参数查询优化假定查询计划成本取决于其值在优化时间未知的参数。例如,这样的参数可以表示未在优化时间完全指定但将在执行时提供的查询谓词的选择性。因此,参数查询优化将每个查询计划与成本函数相关联,该成本函数将从多维参数空间映射到一维成本空间。
优化的目标通常是生成所有可能对任何可能的参数值组合中的最佳的查询计划。这产生了一组相关的查询计划。在运行时,一旦真实的参数值已知,就可以从该集合中选择最佳计划。参数查询优化的优点是,在运行时避免了优化(通常是非常昂贵的操作)。
多目标查询优化
除执行时间外,通常还有其他成本指标与比较查询计划有关。例如,在云计算方案中,人们不仅应该在执行多少时间方面,而且还要在其执行费用上比较查询计划。或在近似查询优化的背景下,可以对输入数据的随机选择示例执行查询计划,以便获得近似结果,并减少执行开销。在这种情况下,必须根据其执行时间进行比较替代查询计划,也必须根据其生成的数据的精确性或可靠性进行比较。
多目标查询优化将查询计划的成本作为成本向量模型,其中每个向量组件根据不同的成本度量表示成本。经典查询优化可以被视为多目标查询优化的特殊情况,其中成本空间的尺寸(即成本向量组件的数量)是一种。
不同的成本指标可能会相互冲突(例如,在云计算方案中可能有一个计划最少的执行时间计划,而货币执行费最少)。因此,优化的目标不能是找到一个最小化所有成本指标的查询计划,但必须找到一个查询计划,以实现不同成本指标之间最佳折衷的查询计划。最好的妥协取决于用户的偏好(例如,有些用户可能更喜欢更便宜的计划,而另一些用户则喜欢在云方案中更快的计划)。因此,优化的目的是根据提供优化器输入的用户偏好的某些规范找到最佳查询计划(例如,用户可以在不同的成本度量指标之间定义权重以表达相对重要性或在某些指标上定义硬性成本范围)或生成一组帕累托最佳查询计划的近似值(即,根据所有指标,没有其他计划的成本更好),以便用户可以从计划集中选择优先的成本折衷方案。
多目标参数查询优化
多目标参数查询优化概括了参数和多目标查询优化。根据多个成本指标进行比较,计划成本可能取决于其优化时间未知的参数。因此,查询计划的成本被建模为从多维参数空间到多维成本空间的函数。优化的目的是生成一组查询计划,对于参数值和用户偏好的每种可能组合而言,这些计划都可以是最佳的。
许多工具显示查询执行计划,以显示哪些操作的处理成本最高。 Microsoft SMS,Apexsqlplan,Hana和Tableau就是一些例子。解决这些计划中发现的这些问题可能会刮除数百分比的执行时间,在某些情况下可以将二维搜索切成线性搜索。
主要和最简单的优化清单之一是使用大多数RDM旨在有效执行的操作。见萨格利。