我之前发布了一个关于根据某些标准加入两个表格的问题 How to join two tables based on a timestamp (with variance of a few seconds)?(链接无需阅读)
我发现创建索引后它的工作速度非常快。我当前代码的片段是
CREATE INDEX INDEXNAME1 ON TABLEA (CALL_DATE+5/86400);
CREATE INDEX INDEXNAME2 ON TABLEA (CALL_DATE+6/86400);
CREATE INDEX INDEXNAME3 ON TABLEB (NUMBER1,NUMBER2);
CREATE INDEX INDEXNAME4 ON TABLEA (NUMBER1,NUMBER2);
----
INSERT INTO AB_RECON (
SELECT A.*,B.* FROM TABLEB B FULL OUTER JOIN TABLEA A
ON B.NUMBER1=A.NUMBER1 AND B.NUMBER2=A.NUMBER2 AND
B.CALL_DATE-A.CALL_DATE IN (5/86400,6/86400);
----
DROP INDEX INDEXNAME1;
DROP INDEX INDEXNAME2;
DROP INDEX INDEXNAME3;
DROP INDEX INDEXNAME4;
不要担心代码的正确性,它可行。但我面临的问题是执行时间非常随机。 90%的时间,执行时间非常快(2-5分钟),但有时(比如现在它的运行时间超过20分钟)。 我知道这似乎“取决于桌子的大小”,但平均而言 TABLEA有140万条记录,TABLEB有900万条记录。 +或 - 几万,而不是更多。
我运行以下代码(作为SYS运行)以识别当前在数据库上运行的查询以及已用时间
select sess.sid, sess.serial#, sess.sql_id, sess.last_call_et as
EXECUTION_TIME,sq.sql_text from v$session sess,v$sql sq
where status = 'ACTIVE' and last_call_et > sysdate - (sysdate - (3/86400))
and username is not null and sess.sql_id=sq.sql_id;
我得到以下输出
SID || SERIAL# || SQL_ID || EXECUTION_TIME || SQL_TEXT
246 || 51291 || dxa2sz103vt0g || 1256 || <my recon query pasted above>
我不明白从它看起来如此长的原因,它是唯一的活跃查询。我不是DBA,所以我不完全理解我是否缺少某些东西。
如果能够解决可能的原因/解决方案,以便我能够指出自己正确的方向,我将不胜感激。
必要时的附加信息
解释计划
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 2386K| 530M| | 2395M (1)|999:59:59 |
| 1 | LOAD TABLE CONVENTIONAL | AB_RECON | | | | | |
| 2 | VIEW | | 2386K| 530M| | 2395M (1)|999:59:59 |
| 3 | UNION-ALL | | | | | | |
|* 4 | HASH JOIN RIGHT OUTER| | 1417K| 109M| 49M| 10143 (1)| 00:02:02 |
| 5 | TABLE ACCESS FULL | TABLEA | 968K| 38M| | 1753 (1)| 00:00:22 |
| 6 | TABLE ACCESS FULL | TABLEB | 1417K| 52M| | 2479 (1)| 00:00:30 |
|* 7 | FILTER | | | | | | |
| 8 | TABLE ACCESS FULL | TABLEA | 968K| 38M| | 1754 (1)| 00:00:22 |
|* 9 | TABLE ACCESS FULL | TABLEB | 1 | 29 | | 2479 (1)| 00:00:30 |
Oracle Edition Oracle Database 11g企业版11.2.0.3.0 64位生产
答案 0 :(得分:0)
好的,我没有真正找到我的问题的答案,但我确实找到了解决方法。 我把我想做的事情(基本上是两种信息来源之间的和解)分解为三个部分。
我使用的查询如下。总的来说它运行得更快。将不得不监视其在多次执行中的表现。
INSERT INTO AB_RECON (
SELECT M.*,I.* FROM TABLEA M, TABLEB I
WHERE M.ANUMBER=I.ANUMBER AND M.BNUMBER=I.BNUMBER
AND M.CALL_DATE-I.CALL_DATE B (5/86400,6/86400));
COMMIT;
INSERT INTO AB_RECON
(SELECT ANUMBER,BNUMBER,CALL_DATE,CALL_DURATION,REF_NO,NULL,NULL,NULL,NULL,NULL FROM
(SELECT * FROM TABLEA M WHERE NOT EXISTS
(SELECT ANUMBER,BNUMBER,CALL_DATE,CALL_DURATION,REF_NO FROM AB_RECON I
WHERE M.ANUMBER=I.ANUMBER AND M.BNUMBER=I.BNUMBER AND M.CALL_DATE=I.CALL_DATE
)
)
);
COMMIT;
INSERT INTO AB_RECON
(SELECT NULL,NULL,NULL,NULL,NULL,ANUMBER,BNUMBER,CALL_DATE,CALL_DURATION,REF_NO FROM
(SELECT * FROM TABLEB M WHERE NOT EXISTS
(SELECT ANUMBER,BNUMBER,CALL_DATE,CALL_DURATION,REF_NO FROM AB_RECON I
WHERE M.ANUMBER=I.ANUMBER AND M.BNUMBER=I.BNUMBER AND M.CALL_DATE=I.CALL_DATE
)
)
);
老实说,我不知道为什么这个工作更快的理论。所以我的主要问题仍然没有得到解决。