如果在关系DBMS中写入查询Q,那么无论一个人如何制定Q,优化器都不会选择执行它的最佳方式(取决于多个因素)?我对SQL Server和Oracle感到好奇。
例如,让Q为:
SELECT *
FROM t1, t2
WHERE t1.some_column = t2.some_column
如果存在正确的索引(具有正确的选择性),我们应该看到索引搜索,可能是密钥查找。我们不会看到的是交叉产品,然后在执行计划中进行选择。
那么为什么FAQs声明“在Transact-SQL中,包含子查询的语句与不包含子查询的语义等效版本之间通常没有性能差异。但是,在某些情况下,存在必须是检查,连接产生更好的性能。“无论你如何编写查询Q,无论Q的查询类(SPJ,SPJ + UNION,SPJ +子查询等),优化器都不会找到最佳的语义等效版本?
谢谢!
答案 0 :(得分:1)
赢得优化器选择最佳执行方式(取决于多个因素),无论一个人如何制定Q?
我想引用本书中的Itzik Ben-Gan的话:Microsoft SQL Server 2012 High-Performance T-SQL Using Window Functions
这有几个原因。
首先,SQL Server的优化器并不完美。我不想要 听起来不高兴 - 当你想到这个时,SQL Server的优化器确实是一个奇迹 软件组件可以实现。但事实是它没有所有可能的优化 其中编码的规则。
二,优化器必须限制优化所花费的时间;否则,它可能花费更长的时间来优化查询而不是时间量 优化会从查询的运行时间中消失。
这种情况可能与在几十毫秒内制定计划而没有超越所有可能的计划并获得仅仅几秒钟的运行时间一样荒谬,但产生所有可能的计划,希望能够在几秒钟内完成削减需要一年甚至几年。您可以看到,出于实际原因,优化器需要限制优化所花费的时间。
根据查询中涉及的表的大小等因素,SQL Server计算两个值:一个是成本考虑因素 - ERED 够好了 对于查询,另一个是花费的最长时间 停止前的优化。如果达到任一阈值,优化将停止,并且SQL Server 使用当时发现的最佳计划。
总之,很少有语句被优化,很少没有
答案 1 :(得分:0)
绝对不是。大多数时候,这将是最好的方法之一,但是总是最好的吗?没有。 优化器必须处理应用于任何包含任何数据的任何模式的任何语句。具有完全相同的逻辑(总是响应相同的数据结果)的两个不同的查询可能会有不同的执行计划。
答案 2 :(得分:0)
对于非平凡的查询,它很可能不会为您提供最优化的执行计划。原因之一是找到最佳优化查询重写是一个np难题。例如,用于成本最小化的连接顺序被认为是np-hard(从n个节点生成的可能树的数量为n ^(n-2) Cayley's formula),而成本函数是启发式的(基于诸如基数,稀疏性,存储模型等属性)。联接排序只是联接优化工作的一部分,而联接优化本身是整个查询优化工作的一部分。