代码之家  ›  专栏  ›  技术社区  ›  FrustratedWithFormsDesigner

查询中的逻辑成本

  •  1
  • FrustratedWithFormsDesigner  · 技术社区  · 16 年前

    我有一个类似这样的查询:

    select xmlelement("rootNode",
        (case
           when XH.ID is not null then
         xmlelement("xhID", XH.ID)
           else
         xmlelement("xhID", xmlattributes('true' AS "xsi:nil"), XH.ID)
        end),
        (case
           when XH.SER_NUM is not null then
         xmlelement("serialNumber", XH.SER_NUM)
           else
         xmlelement("serialNumber", xmlattributes('true' AS "xsi:nil"), XH.SER_NUM)
        end),
    /*repeat this pattern for many more columns from the same table...*/
    FROM XH
    WHERE XH.ID = 'SOMETHINGOROTHER'
    

    它很难看,我不喜欢它,而且它也是执行速度最慢的查询(还有其他类似形式的查询,但是要小得多,而且它们还没有造成任何重大问题)。维护相对容易,因为这主要是生成的查询,但我现在关心的是性能。我想知道对于所有这些case表达式有多少开销。

    为了查看是否存在任何差异,我编写了另一个版本的查询,如下所示:

    select xmlelement("rootNode",
                       xmlforest(XH.ID, XH.SER_NUM,...
    

    (我知道这个查询不会产生完全相同的结果,我的计划是将处理重命名和xsi:nil属性的逻辑移动到xsl或pl/sql)

    我试图得到两个版本的执行计划,但它们是相同的。我猜逻辑不会被考虑到执行计划中。我的直觉告诉我第二个版本应该执行得更快,但我想用一些方法来证明这一点(除了在查询之前和之后用时序语句编写一个pl/sql测试函数,并反复运行该代码以获取测试样本)。

    有没有可能知道这个案子什么时候收费?

    另外,我可以在使用decode函数时编写这个案例。这会比案例陈述更好吗?

    3 回复  |  直到 16 年前
        1
  •  1
  •   Dave Markle    16 年前

    除了用户定义的函数读取表或视图或嵌套的子select之外,选择列表中的任何内容通常都可以忽略,以便分析查询的性能。

    打开连接属性并将值set statistics io设置为on。查看正在进行的读取次数。查看查询计划。您的索引使用是否正确?你知道如何分析要看的计划吗?

        2
  •  1
  •   APC    16 年前

    为了进行性能优化,您将处理以下语句:

    SELECT *
    FROM XH
    WHERE XH.ID = 'SOMETHINGOROTHER' 
    

    该查询如何执行?如果它比XML版本返回的时间短得多,那么您需要考虑函数的性能,但是如果是这样的话,我会很惊讶(噢,呵呵!).

    这是返回一行还是多行?如果只有一行,那么您只有两件事要处理:

    • 是否索引了xh.id,如果是,是否使用了索引?
    • “同一表中的多个列”是否表示 chained rows ?

    如果查询返回多行,则…嗯,实际上你有两件事要做。只是重点在索引方面有所不同。如果索引的聚类因子非常差,那么可以更快地避免使用索引进行全表扫描。

    除此之外,您还需要了解物理问题——I/O瓶颈、互连不良、磁盘不可靠。优化查询的范围之所以如此受限,是因为(如图所示)它是一个单表、单列读取。大多数调优是关于有效连接的。现在,如果XH是一个复杂查询的视图,那么它是一个不同的问题。

        3
  •  0
  •   jim mcnamara    16 年前

    您可以使用好的旧tkprof来分析统计数据。打开统计信息收集的多种形式的alter会话之一。如果光标位于pl/sql代码块中,dbms_profiler包还收集统计信息。