查询优化器的类型和内部工作原理是什么?

时间:2010-04-14 06:46:23

标签: sql-server oracle db2 informix

据我了解,大多数查询优化器都是“基于成本的”。其他人是“基于规则的”,或者我认为他们称之为“基于语法”。那么,优化SQL语句语法以帮助优化器产生更好结果的最佳方法是什么?

某些基于成本的优化器可能会受到FIRST_ROWS()等“提示”的影响。其他是针对OLAP量身定制的。是否有可能知道有关Informix IDS和SE的优化器如何确定处理查询的最佳路径(SET EXPLAIN除外)的更详细逻辑?是否有任何文档说明SELECT语句的排名是什么是访问行的最快方式,假设它被索引?

我认为“SELECT col FROM table WHERE ROWID = n”是最快的(排名1)。

如果我没有误会,Informix SE的ROWID是一个SERIAL(INT)允许最大值。 2GB的nrows,或者它可能使用INT9作为TB的nrows? SE的优化器是基于成本的,当它有足够的数据但不使用像IDS优化器这样的分发。

IDS'ROWID不是INT,它是行左侧页面的逻辑地址 移位8位加上包含行数据的页面上的插槽号。

IDS'优化器是一种使用数据的基于成本的优化器 关于索引深度和宽度,行数,页数和 数据分布由更新统计数据MEDIUM和HIGH创建来决定 哪个查询路径最便宜,但是没有语句排名?

我认为Oracle对ROWID使用HEX值。太糟糕的ROWID不能经常使用,因为行ROWID可以改变。那么也许ROWID可以被优化器用作报告查询进度的计数器?我在“查询完成之前开始查看查询结果”问题中提到了一个想法?我觉得在处理过程中报告查询的进度并不困难,可能是以一些轻微的开销为代价,但提前知道会很好:一个“类似Google”的估计会遇到多少行一个查询的标准,每隔100,200,500或1,000行显示它的进度,让用户能够随时取消它并在它们被放入当前列表时开始显示符合条件的行,同时继续搜索?..这只是一个例子,也许我们可以想到其他整洁/有用的功能,ingridients或多或少存在。

也许我们可以使用比当前可用的更细粒度来微调每个查询? OLTP查询通常主要是静态的和预定义的。 “假设”是更多的OLAP,那么让我们尝试为它添加更多的控制和智能?因此,能够更精确地控制,而不仅仅是“提示/影响”优化器是需要的。然后,我们可以针对特定情况使用更多动态SELECT语句!甚至可以告诉IDS一次读取索引节点的块而不是一个一个等等。

2 个答案:

答案 0 :(得分:1)

我不确定你的目标是什么,但这里有一些我最近读过的SQL Server查询优化器的信息:

13 Things You Should Know About Statistics and the Query Optimizer

SQL Server Query Execution Plan Analysis

和我刚刚使用google找到的一个Informix:
Part 1: Tuning Informix SQL

答案 1 :(得分:1)

对于Oracle,您最好的资源是Cost Based oracle Fundamentals。它大约有500页(并且被称为第1卷,但还没有任何后续内容。)

对于(非常)简单的全表扫描,有时可以通过v $ session_longops监视进度。 Oracle知道它需要扫描多少块,扫描了多少块,需要扫描多少块,以及进度报告。

索引是另一回事。如果我搜索客户端'Frank'的记录并使用索引,数据库将猜测表中有多少'Frank'条目,但该猜测可以大量关闭。可能你有1000'弗兰肯斯坦'而只有1'弗兰克',反之亦然。

当您添加其他过滤器和访问谓词(例如,可以选择多个索引)时,它会变得更加复杂,并且当您包含表连接时会进行另一次飞跃。而且没有涉及远程数据库,Oracle Text和Locator等域索引的复杂内容。

简而言之,它非常复杂。知道您是否负责调整大型应用程序是很有用的。即使对于基本开发,您也需要了解数据库如何物理检索您感兴趣的数据。

但我会说你在这里做错了路。 RDBMS的目的是抽象细节,以便在大多数情况下,它们就会发生。 Oracle聘请聪明的人将查询转换内容编写到优化器中,这样我们开发人员就可以摆脱“语法摆弄”以获得最佳计划(不完全,但它会越来越好)。