2016-09-02 3 views
4

우리는 생산에있어서 고유 한 문제가 있습니다. 한밤중에 배치주기 동안 Oracle 12c 데이터베이스가 매번 끊어 질 것입니다. 며칠/몇 주 동안 계속 진행하려면 데이터베이스를 다시 시작해야합니다. 그런 다음 다시 발생합니다. 나는 테이블의 이름을 변경 한오라클의 신비한 데카르트 제품

UPDATE c_bill SET reason_desc = (SELECT description FROM codes 
WHERE code_group = 'TRANSACTION_TYPE' AND code = c_bill.reason_code); 

-하지만 코드 테이블은 코드와 설명이 : 뒷조사 후, 우리는이 SQL로 좁혀왔다. 개발자가이 설명을 c_bill 테이블에 복사하려고합니다.

이 SQL은 일괄 처리 작업의 일부로 야간에 실행되는 저장 프로 시저의 일부입니다. 개발자는 벌써 진행중인 다른 업데이트를 수행하지만이 SQL은 오랜 시간이 걸립니다.

특정 실행 중에 테이블에는 36308 개의 행이 있습니다. = 36,308 *

Rows_processed을 위의 갱신 1,318,270,864하기위한 곳 중 1 번째로 갱신 36,308 Rows_processed을 위해, 그것은 수 happpens : 나는 생산 DB (내가 브이 $ SQL 테이블에서 SQL을 볼)을 확인하면, 다음과 같은 참조 36308 !! (데카르트 제품?)

TEST에서는이 문제가 없습니다. 내가 UPDATE를 시도하고 TEST에서 계획 한대로 설명해도 아무런 문제가 없습니다. UPDATE와 v $ sql에서 정확히 36308 개의 행을 보여줍니다.

이것은 수수께끼입니다. 누구든지 SQL에서 데카르트 제품의 기회를 볼 수 있습니까? 또는 오라클 12c 옵티마이 저가 Cartesian 제품으로 바꿀 수있는 버그를 알고 있습니까? (그룹별로 버그를 수정하기 위해 일부 패치를 적용했습니다!)

오라클에 대한 상당한 경험이 있습니다. 여기에서 쿼리를 조정합니다. 개발자에게 어디에 where 조건을 추가 할 것을 제안했습니다. 우리는 아직 그것을 테스트하고 있습니다. 그동안 오라클 전문가가 귀하의 의견을 듣고 싶었습니다. 모든 의견/제안을 주셔서 감사합니다.

UPDATE : 앞으로이 게시물을 찾고 사람을위한 - 문제는 데카르트의 제품이 아니라 문제가 업데이트 SQL은 따라서 데카르트처럼 보이는, 일 같은 테이블에 커서 루프에서 실행. 저스틴의 대답을보십시오.

+1

''v $ sql' 1에서'실행 '입니까? 아니면 36308입니까 (즉, 36308 실행에서 36308 개의 행이 업데이트되었습니다)? 공유 풀 또는 AWR/Statspack에서 쿼리 계획을 가져 와서 실제로 데카르트 제품이 있는지 확인할 수 있습니까?'c_bill'는'code_group' 또는'code'라는 이름의 열을 가지고 있습니까? 아니면'codes'에만 존재합니까? –

+0

나는 네가 그것을 못질 것 같아! Executions = 36308이고 예를 들어있는 프로 시저에는 c_bill 테이블의 키에 대한 행을 선택하는 커서가 있습니다. 앞서 언급 한 이전 업데이트에서는 실제로 커서 SQL에 사용 된 키가 있지만이 키는 사용하지 않았습니다. 나는 더 많은 테스트와 포스트 백을 할 것이다. 나는 DBA가 아니며 다음주에 AWR 통계를 점검 할 것입니다. 답변으로 다시 게시 해 주시겠습니까? – SamV

+0

v $ sql에서 문제 UPDATE 문에 대한 last_load_time은 last_load_time이 2016-09-02/03 : 04 : 02 이고 last_active_time이 09/02/2016 4:48이었습니다. 이것은 동일한 SQL이 그 시간 동안 36308 번 실행되는 것을 의미합니까? – SamV

답변

1

첫 번째 생각은 데카르트 제품을 수행하는 나쁜 계획이 있다는 이론을 확인하거나 반박하는 증거를 수집하려고하는 것입니다. 은 v$sql에 있습니까? 아니면 36308? 1 일 경우 카티 전 곱 이론을 지원할 것이고 언제 이런 일이 발생했는지, AWR 사용 허가를 받았는지 여부에 따라 v$sql_plan 또는 dba_hist_sql_plan의 쿼리 계획을 찾기 시작할 것입니다. 반면 36308이면 쿼리가 36308 개의 행을 업데이트하고 있음을 의미하지만 무언가가 테이블의 모든 행을 반복하려고하기 때문에 36308 번을 호출하게됩니다.

+0

좋은 답변입니다! 수수께끼를 찾아내는 데 도움이되었습니다. DBA가 오늘 아침 그리드 컨트롤에서 가장 많은 활동 차트를 보냈을 때 한 SQL이 그렇게 오래 걸리는 것처럼 보였습니다. 당신이 말했듯이, 실제로 그것은 1 시간 이상 계속 실행되는 캐시 된 SQL입니다. 오늘 아침에 문제를보기 시작했는데 외부 루프가 같은 테이블을 사용하고 있지 않았다. 저를위한 그것을 좁히는 주셔서 감사합니다! – SamV

1

여기서 설명하는 동작에 대한 특별한 이유는 알지 못합니다. 어쨌든, 해결 방법으로, 당신은 이와 같은, 다른 업데이트 시도 할 수 : 나를 실제로 현재 오라클에이 문을 시도하는

UPDATE 
    (SELECT c_bill.reason_desc oldDesc, codes.description newDesc 
    FROM c_bill INNER JOIN codes ON 
     code.code_group = 'TRANSACTION_TYPE' AND 
     codes.code = c_bill.reason_code) 
SET oldDesc = newDesc 

불행하게도, 그것은 어렵다. 나는 전에 이런 종류의 업데이트를 본 것을 안다.

+0

귀하의 제안에 대해 @Zoran에게 감사드립니다. 나는 그것을 시험해 보았다. 그것은 그것이 부족한 조건을 확실히 추가한다. 그러나 SQL은 이전 버전보다 훨씬 뛰어나다. 저스틴 케이브 (Justin Cave)의 의견을 바탕으로, 나는 사형을 보았고 그곳에서 36308 번을 실행했다 !! 그래서, 나는 조건이 그것을 데카르트 제품처럼 보이게하지 않고 루프 안에있는 SQL을 생각합니다. 나는 그것을 시험 한 후에 나의 발견을 다시 게시 할 것이다. – SamV

+1

귀하의 질문은 매우 유익했습니다, 나는 우리 모두가 그것으로부터 무언가를 배웠다고 생각합니다. –

관련 문제