介绍
多年来,商业数据库制造商为提高数据库中存储信息的插入、更新、删除和检索性能进行了不懈的努力。尽管如此,大多数关系型数据库管理系统(RDBMS)的性能仍未得到明显改善:您仍在处理性能欠佳的SQL语句。
似乎您唯一的选择是反复的重写。但是,如果您不必浪费数小时来优化SQL语句呢?使用Quest SQL Optimizer,您可以自动提高SQL语句的性能。这意味着您可以节省时间,降低风险并专注于其他高优先级项目。
让我们来看看此类更强大的解决方案,是如何通过效仿人类的技术来克服内部数据库管理系统中的SQL优化器的局限性。
内部数据库 SQL 优化器所面临的挑战
严重的缺陷导致数据库的内部SQL优化器无法为SQL语句找到良好的执行规划。这些缺陷包括不正确的数据库统计信息和可用于SQL语句资源的成本估算。
索引统计信息不能及时更新。
批处理模式统计信息收集和实时数据采样技术是收集数据库统计信息的两种常用方法。批处理模式统计信息收集会处理大量数据并使用系统资源,这需要一段时间来收集数据统计信息。因此,系统管理员们通常在非高峰时间对所要更新的统计信息执行数据收集工作。
如果自上次统计信息收集以来执行了多次插入或删除的操作,那么当执行SQL语句时,这些统计信息将不会反馈最新的数据。这可能会导致数据库SQL优化器为当前的数据分布生成效果不佳的执行计划。
幸运的是,在最近几年中,数据库供应商采用了一种新的实时数据采样技术来改善统计信息的收集。这种技术允许对少量数据进行抽样以收集统计信息。它需要平均分布数据,以便采样数据可以完全反映真实的数据分布。批处理模式统计信息收集则可以在数据分布不均的情况下为数据库生成准确的统计信息。
成本估算不准确
导致数据库SQL优化器无法为SQL语句找到良好的执行规划的第二个原因是成本估算不准确。显然,错误的统计信息将导致不精确的成本估算。即使数据库统计信息正确,但在没有相关信息的情况下,数据库SQL优化器也无法正确确定最佳的执行计划。让我们检查以下SQL:
通过上列SQL语句,我们实现了3个表的连接。我们假定仅当所有统计信息都可用于此SQL语句中的表和索引时,数据库SQL优化器才会使用嵌套循环连接。在此示例中,我们通过查看数据发现,表C→B→A(图1)的驱动路径比A→B→C(图2)所花费的时间更长。 但是大多数数据库SQL优化器都会选择驱动路径C→B→A。发生这种情况是因为C.f2具有唯一索引,并且数据库SQL优化器并不知道需将从C.key2中返回哪些值。从该示例可以看出,检索的记录数量以及处理执行计划的成本需要数据本身来确定。而数据库SQL优化器并没有获得此信息,因此无法选择最佳的执行计划。
(图1:驱动路径从表C到表B,与表B的四行匹配。然后这四行与表A匹配。表B中灰色行显示了两条使用此驱动路径导致额外扫描操作的记录)
(图2.驱动路径从表A到表B,该表匹配两行。然后,使用这两行与表C中的行进行匹配。因此,通过该驱动路径,无需执行不必要的表扫描。虽然需从选择性较低的条件开始筛选,但整体扫描结果将更为乐观)
设计SQL内部数据重写功能所面临的挑战
如今,大多数数据库管理系统中的内部SQL优化器具有有限的内置SQL重写功能。内部重写可用于更正一些明显的编程错误或自动输入内部SQL语法。这种内部SQL语法可以使之后的优化阶段更容易将IN或EXISTS子查询转换为JOIN语句,或使用实例化视图。而由于一些数据库的内部SQL重写能力较弱,也给数据库调优专家留下了影响数据库SQL优化器的机会,以便在生成执行计划的后期阶段做出更好的选择。在所有数据库中,Oracle拥有最开放式的体系结构,可以通过使用“hints”优化机制,按照用户的方式生成执行计划。同时Oracle还是对语法最为敏感的数据库,它允许用户通过重组SQL语法来调整其SQL语句。
相反,像IBM DB2 UDB(通用数据库)这样的数据库具有非常强的内部SQL重写能力。在此程序中,大多数SQL语句可以在进一步优化之前转换为内部SQL语法。这意味着使程序员不必调整他们的SQL语句,因为数据库SQL优化器将为他们完成这项工作。但这样也可能会出现问题,比如当数据库SQL优化器在某些特定的SQL语句上出错时,程序员很难在此情况下选择其他选项。
这样的现状透露出了一个数据库工程师始终面临的困境:他们是否应该让数据库变得更加智能,始终为用户做出明智的选择?还是应该给用户控制的权利,因为数据库SQL优化器不会总是自动做出最好的选择?
上一条:Toad for IBM DB2,专业的数据库开发工具
下一条:TOAD FOR IBM DB2使用技巧