2012-08-01 53 views
1

我有查询在Oracle中,看起来像这样:甲骨文子查询消耗了大量的时间

SELECT 
    t1.tid, t1.column1, t1.column2 
    FROM 
    table1 t1 
    JOIN 
    log_table lg ON t1.tid = lg.tid 
    WHERE 
    t1.insert_date > lg.date_of_insert 
    AND lg.log_id = (SELECT MAX(log_for_last.log_id) FROM log_table log_for_last WHERE lg.tid = log_for_last.tid) 
    AND t1.insert_date = (SELECT MAX(t1_last_date.insert_date) FROM table1 t1_last_date WHERE t1_last_date.tid = t1.tid); 

但它消耗了大量的时间来完成。问题是在这一行:

AND t1.insert_date = (SELECT MAX(t1_last_date.insert_date) FROM table1 t1_last_date WHERE t1_last_date.tid = t1.tid); 

t1.tid必须是唯一的。我该如何优化这个查询?

编辑:

我尝试以下,但它给了我SQL错误:ORA-00904: “RN”:无效的标识符错误:事先

SELECT 
    t1.tid, t1.column1, t1.column2, 
    ROW_NUMBER() OVER (ORDER BY t1.insert_date DESC) rn 
FROM 
    table1 t1 
    JOIN 
    log_table lg ON t1.tid = lg.tid 
WHERE 
    t1.insert_date > lg.date_of_insert 
    AND lg.log_id = (SELECT MAX(log_for_last.log_id) FROM log_table log_for_last WHERE lg.tid = log_for_last.tid) 
    AND rn = 1 

感谢

+1

使用分析函数可能是最好的选择。但是您需要使用内联视图来基于'rn'进行过滤:“分析函数是查询中执行的最后一组操作,除了最终的ORDER BY子句之外,所有连接以及所有WHERE,GROUP BY和HAVING子句在处理分析函数之前完成,因此分析函数只能出现在选择列表或ORDER BY子句中。“ http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions004.htm#i81407 – 2012-08-01 06:23:24

回答

4

我解决我的问题,如:

SELECT * 
FROM 
(
    SELECT 
     t1.tid, t1.column1, t1.column2, 
     ROW_NUMBER() OVER (PARTITION BY t1.tid ORDER BY t1.insert_date DESC) rn 
    FROM 
     table1 t1 
    JOIN 
     log_table lg ON t1.tid = lg.tid 
    WHERE 
     t1.insert_date > lg.date_of_insert 
     AND lg.log_id = (SELECT MAX(log_for_last.log_id) FROM log_table log_for_last WHERE lg.tid = log_for_last.tid) 
) 
WHERE rn = 1 

我希望这会有所帮助别人。

0

你能确定为什么这一行花了这么长时间(除了每行评估)。我建议看一下查询计划,看看时间在哪里,可能需要一个新的索引来加速性能,或者一个微妙的重写可能会诀窍。

如果你需要帮助看执行计划,那么我建议从以下开始。

SQL*Plus FAQ - How does one trace (and explain) SQL statements from SQL*Plus?

+0

我无法添加索引,因为此表位于其他架构。 – 2012-08-01 06:05:18

+0

除了查看查询的计划之外,您是否考虑过将其转换为一个过程,并分解子查询? – 2012-08-01 06:20:54

+0

谢谢你的时间@ daz-fuller。我解决了这个问题,现在就会发布 – 2012-08-01 06:23:46