Oracle11g Oracle查询的优化

Oracle11g Oracle查询的优化,oracle11g,Oracle11g,我有以下疑问: SELECT distinct A1 ,sum(total) as sum_total FROM ( SELECT A1, A2,A3,A4,A5,A6,COUNT(A7) AS total,A8 FROM ( select a.* from table1 a left join (select * from table_reject where name = 'smith') b

我有以下疑问:

SELECT distinct A1 ,sum(total) as sum_total  FROM 
    (   
       SELECT  A1, A2,A3,A4,A5,A6,COUNT(A7) AS total,A8
       FROM (
            select a.*  from table1 a 
            left join (select * from table_reject where name = 'smith') b on A.A3 = B.B3 and A.A9 =B.B2
            where B.ID is null
            ) t1
       WHERE A8 >= NEXT_DAY ( trunc(to_date('17/09/2013 12:00:00','dd/mm/yyyy hh24:mi:ss')) ,'SUN' )     
       GROUP BY 
       CUBE(A1, A2,A3,A4,A5,A6,A8)
    )INN
    WHERE 
     INN.A1 IS NOT NULL AND
     INN.A2 IS NULL AND 
     INN.A3 IS NULL AND 
     INN.A4 IS NULL AND
     INN.A5 IS NULL AND 
     INN.A6 is NULL AND
     INN.A8 IS NOT NULL
    GROUP BY A1
    ORDER BY sum_total DESC ;
表1中的记录总数约为800万条。 我的问题是我需要以最好的方式优化上面的查询。我曾尝试在表1的A8列上创建索引,创建索引帮助我降低了查询成本,但当表1上没有索引时,查询的执行时间基本相同

任何帮助都将不胜感激。
谢谢

您正在对七列计算一个可能非常大的多维数据集结果,然后丢弃所有结果,除了逻辑上仅为A1列上的分组结果


我建议您将查询重写为仅按A1分组。

对大型数据集的多维数据集操作非常昂贵,因此您需要检查是否确实需要内部查询中的所有数据。因为我看到您在内部进行计数,然后在外部查询中进行计数总和。换句话说,对于所有组合A1-A8(-A7),给我A7 at的行数。然后仅获取由WHERE子句筛选的选定组合的总和。我们可以通过将立方体限制在某个列上来优化它,但到目前为止,我注意到的非常明显的事情如下

如果您使用下面的查询,并且有正确的索引o Table1和Table_reject,那么这两个查询都可以利用索引并减少需要联接和进一步处理的数据集。 我不是100%确定,但是的,部分立方体处理是可能的,需要检查

聚集索引-->表1需要在A8上,表U需要在名称上聚集索引

A3、A9上的非聚集索引-->表1需要,B3、B2上的表_拒绝需要

    SELECT qry1.
    (
        SELECT  A1, A2,A3,A4,A5,A6,A7,A8
        FROM table1
        WHERE A8 >= NEXT_DAY ( trunc(to_date('17/09/2013 12:00:00','dd/mm/yyyy hh24:mi:ss')) ,'SUN' )
    )qry1
    LEFT JOIN
    (
        select B3,B2,ID
        from table_reject 
        where name = 'smith'
    )qry2
        ON qry1.A3 = qry2.B3 and qry1.A9=qry2.B2
    WHERE qry2.ID IS NULL
EDIT1:

我试图找出,如果对所有列执行多维数据集操作符,或者只对结果集中需要它的列执行多维数据集操作符,结果会有什么不同。我发现的是多维数据集函数的工作方式,您不需要对所有列执行多维数据集。因为最后您只关心由立方体生成的组合,其中A1和A8不为NULL。 尝试此链接并查看输出

查询1和查询2只是比较多维数据集结果集的最内部查询

Query3和Query4是您正在尝试的同一个查询,并且您看到的结果在这两种情况下都是相同的

    DECLARE @NEXT_DAY DATE = NEXT_DAY ( trunc(to_date('17/09/2013 12:00:00','dd/mm/yyyy hh24:mi:ss')) ,'SUN' )

    SELECT distinct A1 ,sum(total) as sum_total  FROM 
    (   
       SELECT  A1,COUNT(A7) AS total,A8
       FROM (
                select a.a1,a.a7,a.a8  
                from table1 a
                left join  (select * from table_reject where name = 'smith') b 
                on A.A3 = B.B3 and A.A9 =B.B2
                where B.ID is null
            ) t1
       WHERE A8 >= @NEXT_DAY
       GROUP BY 
       CUBE(A1,A8)
    )INN
    WHERE   INN.A1 IS NOT NULL AND
            INN.A8 IS NOT NULL
    GROUP BY A1
    ORDER BY sum_total DESC ;
EDIT3

正如我在评论中提到的,这是第三轮更新。我不能改变评论,但我的意思是Edit3而不是Round3

您查询中的新更改是在最左侧的join select
中添加
其中A8>=@NEXT\u DAY
条件,其中A8>=@NEXT\u DAY和B.ID也是null
。这大大改进了选择

在您上次的评论中,您提到查询需要30-35秒,当您更改A8的值时,它会不断增加。关于执行时间,您没有提到结果集中有多少数据为什么这很重要?因为如果我的查询返回500万行作为最终结果集,那么将花费90%的时间将数据拖放到UI或输出文件中,即您正在使用的任何输出方法。但实际性能应该衡量查询开始给出前几行的时间。因为此时优化器已经决定了执行计划,DB正在执行该计划。但我同意,若查询返回100行并花费10秒,那个么执行计划可能有问题

为了演示我所做的是创建虚拟数据。并对它执行了你的查询。 我有一个表Test_CubeData,其中有9M行,列号和数据类型与您为表1解释的相同。我有第二个表table_Reject,它有80K行,列数和我从查询中得出的数据类型。测试该表的极端侧;name列只有一个值“smith”,所有80K行的ID都为空。所以,可以影响左内联接结果的列值将是B2和B3

在这些测试中,两个表上都没有任何索引。两者都是堆。您可以看到,在结果集中数据的可接受范围内,结果只需几秒钟。随着结果数据集的增加,完成时间也随之增加。如果我创建解释索引,那么它将给我索引查找操作 对于所有这些测试案例。但在某一点上,索引也将耗尽并成为索引扫描。 一个确定的例子是,如果A8列的筛选值是该列中存在的最小日期值。在这种情况下,优化器将看到所有9M行都需要参与内部选择和多维数据集,大量数据将在内存中得到处理。这是意料之中的。另一方面,让我们看看另一个查询示例。我在A8列中有唯一的32873个值,这些值几乎平均分布在9M行中。因此,每个A8值有260到300行。现在,如果我对任何单个值执行查询,那么查询执行时间不应该改变

请注意下面每个图像中突出显示的文本,该文本指示选择了A8过滤器的值, 仅选择列表中的重要列,而不是使用*,在左内连接查询中添加了一个8过滤器,执行计划显示表CAN对两个表的操作,以秒为单位的查询执行时间,以及查询返回的总行数

我希望这将消除对查询性能的一些疑虑,并帮助您设定正确的期望

**Table Row Counts**


您可以发布表结构和列数据类型,列可为空的类型吗。您是否考虑过多维数据集的多维数据集如何取空值?嗨,Anup,我试图使用您所建议的部分立方体操作的概念。事实上,我已经实现了您给我的相同查询,并且查询的输出是相同的。但是,查询的执行时间仍然超过30-35秒,并且在我更改值列(即A8(Date_列))时,它会不断增加。当我看到ful的解释计划成本时
**TableScan_InnerLeftJoin**
**TableScan_FullQuery_248Rows**
**TableScan_FullQuery_5K**
**TableScan_FullQuery_56K**
**TableScan_FullQuery_480k**