如何使我的查询更有效?

时间:2014-05-29 20:59:59

标签: sql database oracle toad

我在使用Toad的Oracle SQL环境中运行查询,我通过连接16个不同的表来构建表,并且我正在运行临时表空间,并且希望我能获得有关如何提高查询效率的建议。我没有这方面的背景,所以我不确定最好的方法是使用中间表还是改变我的连接顺序。

有两个主要表,Header和Detail,标题有2600万行,详细信息有1.75亿行。我使用这些表的内连接,这将导致1.75亿行。其他14个表是我使用左连接加入的较小描述表。其中三个表是350k行甚至更少,另外11个是1000行以下。我目前的伪代码如下:

    create table END_TABLE as
    select *
    from Detail
    inner join Header
    left join description_table_1
    left join description_table_2
    left join description_table_3
    left join description_table_4
    left join description_table_5
    left join description_table_6
    left join description_table_7
    left join description_table_8
    left join description_table_9
    left join description_table_10
    left join description_table_11
    left join description_table_12
    left join description_table_13
    left join description_table_14;

因为我从我的详细信息表开始,然后加入标题的效率低于我反过来的效率吗?我认为,因为它是一个内部联接,所以没关系,但就像我之前所说的那样,我对提高查询效率并不是很了解。

我的想法是创建一个单独的表连接标题和细节,然后创建一个最终表,我加入较小的细节表。这会有帮助吗?更改我的加入顺序会有帮助吗?

4 个答案:

答案 0 :(得分:1)

你正在加入一个包含1.75亿行的表,另一个表有2600万行,没有索引,没有where子句。

你需要指数。没有他们,你只是在泰坦尼克号的躺椅上拖着脚走路。

答案 1 :(得分:1)

指数很可能无济于事:

当您完全连接两个表时,Oracle很可能会对两个表执行FULL TABLE SCAN,使用HASH JOIN,并且不会考虑使用索引。

您可以尝试对Header和Detail表进行分区,然后在循环中一次连接一个分区,并将结果插入END_TABLE表。

答案 2 :(得分:0)

根据我在Oracle 11g上的经验,当我处理大型表的许多连接时,我发现在每个步骤中使用中间表连接较少的情况下经常会大大加快(在一个案例中,一步需要7个小时)分多步花了大约20分钟)。可能我会将Detail和Header加入到一个表中,然后一次将这个中间表连接到1-3个描述表,然后开始组合那些进一步的中间表。你说你没有索引:我希望索引可以加速连接,即使你没有排除约束中的任何数据。也许你不能在主表上有索引,但是如果你走这条路,你可能能够用于中间表。请记住,在数据发生变化的情况下,您需要考虑是否在整个查询系列中维护一个事务。

答案 3 :(得分:0)

  • 如果您的最大数据量大约是表中数据的100%(并且根据您的描述),那么您不需要索引-FTS可以正常工作。
  • 我不是ANSI SQL的忠实粉丝,而是喜欢使用"正确的工具来完成正确的任务" - 并使用Oracle SQL语法和非ANSI,但似乎您没有为连接指定列。从我的回忆中,您只有在使用NATURAL JOIN - WIKI时才需要列。 JOIN的所有其他情况都需要定义哪些列是参与者。
  • 列规范也与LEFT JOIN(LEFT OUTER JOIN)相关 - again