it-swarm.cn

你如何解释查询的解释计划?

在尝试理解SQL语句的执行方式时,有时建议您查看解释计划。在解释(理解)解释计划时应该经历的过程是什么?应该突出的是,“哦,这真的很棒吗?”与“哦不,那不对。”

87
user290

每当我看到评论说完整的桌面卡坏并且索引访问是好的时候,我就会不寒而栗。全表扫描,索引范围扫描,快速完整索引扫描,嵌套循环,合并连接,散列连接等只是分析人员必须理解的访问机制,并结合了数据库结构的知识和查询的目的。为了得出任何有意义的结论。

完全扫描只是读取数据段(表或表(子)分区)的大部分块的最有效方式,虽然它通常可以指示性能问题,但仅在上下文中它是否是实现查询目标的有效机制。作为一个数据仓库和BI人,我的第一个性能警告标志是基于索引的访问方法和嵌套循环。

因此,对于如何阅读解释计划的机制,Oracle文档是一个很好的指南: http://download.Oracle.com/docs/cd/B28359_01/server.111/b28274/ex_plan.htm#PFGRF009

还要通过“性能调优指南”仔细阅读。

还有一个google用于“基数反馈”,这是一种技术,其中解释计划可用于将查询中各个阶段的基数估计与执行期间经历的实际基数进行比较。我相信Wolfgang Breitling是这种方法的作者。

所以,底线:了解访问机制。理解数据库。理解查询的意图。避免经验法则。

78
David Aldridge

在这样的问题中,这个主题太大了,无法回答。你应该花些时间阅读 Oracle的性能调优指南

13
Tony Andrews

下面的两个示例显示了使用INDEX的FULL扫描和FAST扫描。

最好专注于您的成本和基数。查看示例,索引的使用降低了运行查询的成本。

它有点复杂(我没有100%的处理)但基本上Cost是CPU和IO cost的函数,而Cardinality是Oracle期望解析的行数。减少这两者是一件好事。

不要忘记查询和Oracle优化器模型(例如:COST,CHOOSE等)以及运行统计信息的频率会影响查询的成本。

示例1:

扫描http://docs.google.com/a/shanghainetwork.org/File?id=dd8xj6nh_7fj3cr8dx_b

示例2使用索引:

INDEX http://docs.google.com/a/fukuoka-now.com/File?id=dd8xj6nh_9fhsqvxcp_b

如前所述,请注意TABLE SCAN。你通常可以避免这些。

5
Mark Nold

寻找像顺序扫描这样的东西可能有点用处,但实际情况是数字...除非数字只是估计!什么通常比查看查询更有用 计划 正在查看实际的 执行 。在Postgres中,这是EXPLAIN和EXPLAIN ANALYZE之间的区别。 EXPLAIN ANALYZE实际执行查询,并获取每个节点的实时定时信息。这让你可以看到 实际 正在发生什么,而不是计划者 认为 会发生什么。很多时候,您会发现顺序扫描根本不是问题,而是查询中的其他内容。

另一个关键是确定实际的昂贵步骤是什么。许多图形工具将使用不同大小的箭头来指示计划的不同部分成本。在这种情况下,只需查看有细箭头进入并留下粗箭头的步骤。如果你没有使用GUI,你需要注意数字,并寻找它们突然变大的地方。通过一些练习,可以很容易地找出问题区域。

4
decibel

对于像这样的问题,最好的办法是 _ asktom _ 。特别是他对该问题的回答包含在线Oracle文档的链接,其中解释了许多这类规则。

要记住的一点是,解释计划确实是最好的猜测。

学习使用sqlplus并尝​​试使用AUTOTRACE命令是个好主意。通过一些硬数字,您通常可以做出更好的决策。

但你应该ASKTOM。他知道一切:)

3
EvilTeach

解释的输出告诉你每个步骤花了多长时间。首先要找到花费很长时间并了解其含义的步骤。顺序扫描等事情告诉您需要更好的索引 - 这主要是对您的特定数据库和经验的研究。

2
Tom Leys

一个“哦不,那不对”通常采用 表扫描的形式 。表扫描不使用任何特殊索引,可以有助于清除内存缓存中的所有有用内容。例如,在postgreSQL中,你会发现它看起来像这样。

Seq Scan on my_table  (cost=0.00..15558.92 rows=620092 width=78)

有时,表扫描比使用索引查询行更理想。但是,这是您似乎正在寻找的那些红旗图案之一。

2
convex hull

基本上,您可以查看每个操作,看看操作是否“有意义”,因为您知道它应该如何工作。

例如,如果您在各自的列C和D(AC = BD)上连接两个表A和B,并且您的计划在表中显示聚簇索引扫描(SQL Server术语 - 不确定Oracle术语) A,然后嵌套循环连接到表B上的一系列聚簇索引查找,您可能认为存在问题。在这种情况下,您可能希望引擎执行一对索引扫描(通过连接列上的索引),然后进行合并连接。进一步调查可能会显示错误的统计信息,使优化器选择连接模式,或者实际上不存在的索引。

2
Jonathan Rupp

查看计划每个子部分花费的时间百分比,并考虑引擎正在做什么。例如,如果它正在扫描表,请考虑在正在扫描的字段上放置索引

1
Steven A. Lowe

我主要寻找索引或表扫描。这通常告诉我,我在缺少where语句或join语句中的重要列的索引。

来自 http://www.sql-server-performance.com/tips/query_execution_plan_analysis_p1.aspx

如果您在执行计划中看到以下任何内容,则应考虑它们的警告标志并调查它们是否存在潜在的性能问题。从性能角度来看,每个都不太理想。

* Index or table scans: May indicate a need for better or  additional indexes.
* Bookmark Lookups: Consider changing the current clustered index,
  consider using a covering index, limit
  the number of columns in the SELECT
  statement.
* Filter: Remove any functions in the WHERE clause, don't include wiews
  in your Transact-SQL code, may need
  additional indexes.
* Sort: Does the data really need to be sorted? Can an index be used to
  avoid sorting? Can sorting be done at
  the client more efficiently? 

并不总是可以避免这些,但是越多可以避免它们,查询性能就越快。

1
dpollock