2011-08-11 2 views
1

누구나 왜이 쿼리를 실행하려고하면 영원히 멈추지 않고 멈추지 않을까요?Oracle SQL - 왼쪽 테이블 조인 2 테이블에서 실행되지 않습니다.

'With'절 내의 쿼리는 자체적으로 정상적으로 실행됩니다. 그것은 내가 그들과 합류하려고 할 때 나는 제대로 달릴 수 없다.

--Process name and input 
With ProcessIn as 
(
select Data.Scan_time, equipment.equipment_desc, data.serial_number 

from Data, equipment 

where Data.equipment = equipment.equipm_barcode and data.quality_plan = 'N/A' and  data.error_code = 'N/A' 
) 

--Total process defects 
,ProcessDefect as 
(
select Data.Scan_time, equipment.equipment_desc, data.serial_number 

from Data, equipment 

where Data.equipment = equipment.equipm_barcode and (data.quality_plan <> 'N/A' or  data.error_code <> 'N/A') 
) 

Select concat(to_char(ProcessIn.SCAN_TIME, 'mm'), to_char(ProcessIn.SCAN_TIME, 'dd')) as "Date", ProcessIn.equipment_desc, count(ProcessIn.serial_number), count(ProcessDefect.serial_number) 

from ProcessIn 
Left Join ProcessDefect 
On concat(to_char(ProcessIn.SCAN_TIME, 'mm'),to_char(ProcessIn.SCAN_TIME, 'dd')) = concat(to_char(ProcessDefect.SCAN_TIME, 'mm'),to_char(ProcessDefect.SCAN_TIME, 'dd')) 
and ProcessIn.equipment_desc = ProcessDefect.equipment_desc 

group by concat(to_char(ProcessIn.SCAN_TIME, 'mm'), to_char(ProcessIn.SCAN_TIME, 'dd')), ProcessIn.equipment_desc 
; 

UPDATE는 20,110,816 내가 성공하지 내 쿼리를 수정하기 위해 제안의 일부를 사용했습니다. 아무도 다른 제안이 있습니까? 또한 어쨌든 내 색인이 제대로 작성되고 사용되는지 확인해야합니다. 난 오라클 인터페이스를 사용하여 serial_number와 smalldate에 기반한 인덱스를 생성했다.

감사

With ProcessIn as 
(
select data.smalldate, mip.mip_step_description, data.part_serial_number 

from Data, MIP 

where Data.equipment = MIP.equipment and data.quality_plan is null and data.error_code is null 
) 

,ProcessDefect as 
(
select data.smalldate, mip.mip_step_description, data.part_serial_number 

from Data, MIP 

where Data.equipment = MIP.equipment and (data.quality_plan is not null or data.error_code is not null) 
) 

Select ProcessIn.smalldate, ProcessIn.mip_step_description, count(ProcessIn.part_serial_number), count(ProcessDefect.part_serial_number) 

from ProcessIn 
Left Join ProcessDefect 
On ProcessIn.smalldate = ProcessDefect.smalldate 
and ProcessIn.mip_step_description = ProcessDefect.mip_step_description 

group by ProcessIn.smalldate, ProcessIn.mip_step_description 

UPDATE는

110820 그래서 좀 진전하지만 마지막으로 한 가지를 파악하는 데 도움이 필요했습니다. 이처럼 쿼리 구조를 변경했습니다.

select data.smalldate, mip.mip_step_description, error_code.error_code_en, count(case when (error_code is null and quality_plan is null) then data.part_serial_number end) as "Input", count(case when error_code is not null then data.part_serial_number end) as "Defects" 

from Data 

left join MIP 
On data.equipment = mip.equipment 

left join error_code 
on data.error_code = error_code.error_code_sn 

group by data.smalldate, mip.mip_step_description, error_code.error_code_en 

order by data.smalldate, mip.mip_step_description, count(data.part_serial_number) desc 

select 문에서 볼 수 있듯이 count 함수 내에서 case 문을 사용하고 있습니다. 이것은 잘 작동합니다. 이

Date MIP_Desc Error_Code Input Defects 
1/1/2011 MIP Z (null)  100  0 
1/1/2011 MIP Z A   0  10 
1/1/2011 MIP Z B   0  15 

내가 같은 날짜와 MIP가 모든 행에 걸쳐 입력 열에서 같은 입력 값을 작성하고 싶습니다처럼 데이터 출력 보인다.

출력이

Date MIP_Desc Error_Code Input Defects 
1/1/2011 MIP Z (null)  100  0 
1/1/2011 MIP Z A   100  10 
1/1/2011 MIP Z B   100  15 

모든 팁 모양을한다? SQL 서버에서

On concat(to_char(ProcessIn.SCAN_TIME, 'mm'),to_char(ProcessIn.SCAN_TIME, 'dd')) = 
    concat(to_char(ProcessDefect.SCAN_TIME, 'mm'),to_char(ProcessDefect.SCAN_TIME, 'dd')) 

이 : 도움

+1

쿼리 계획을 게시하시기 바랍니다. 실제로 쿼리가 매우 비싸거나 쿼리 계획이 잘못 선택되었을 가능성이 있습니다. – Codo

+0

당신이 쿼리를 구성한 방식으로, 테이블'equipment'는 질의에 두 번 참여하고'equipment_desc' 열을 통해 조인됩니다.이 열은 인덱싱되지 않습니다. 인덱싱 된 열을 통해 조인하는 것이 가능하지 않습니까? – Codo

+0

주제를 벗어나지 만 묵시적 조인 구문 사용을 중단해야합니다. 그것은 SQL Antipattern이며 매우 나쁜 프로그래밍 기술입니다. – HLGEM

답변

1

내가 오라클 개발자 아니지만, 나에게 거대한 붉은 깃발이 당신의 가입 문의 양쪽에 중첩 된 함수 호출을 사용하는 것이다위한 다시 감사합니다 옵티마이 저가 인덱스를 사용하여 조인 조작을 수행하는 데 어려움을 겪게 될 것이라는 아주 강력한 표시입니다. 하위 쿼리가 큰 레코드 세트를 생성하는 경우 JOIN을 완료하는 데 매우 오랜 시간이 걸릴 수 있습니다.

ON 절을 수정하여 함수 호출이 필요하지 않으면 (가능한 경우 양측에 있지만 적어도 하나는 필요함) 성능 향상에 도움이 될 것입니다.

+0

중첩 된 함수가없는 날짜/시간 열에서 날짜와 달을 비교하는 방법에 대한 아이디어가 있습니까 ?? – AFJ

+0

비교 대상에서 제외 할 연도를 제외하고는 적어도 TRUNC (ProcessIn.SCAN_TIME) = TRUNC (ProcessDefect.SCAN_TIME)로 단순화 할 수 있습니다. 그러나 아직 색인을 사용할 수는 없습니다. – Codo

+0

CTE 부분에서 데이터 변환을 수행하면 조인이 더 좋을 수 있습니다. SQL Server에서 인덱싱 할 수있는 임시 테이블에서이 작업 (변환 포함)을 수행 한 다음 조인을 수행하지만 Oracle에서 해당 옵션을 사용할 수 있는지 여부는 알 수 없습니다. 물론 필요한 방식으로 데이터를 저장할 수 있습니다. 그런 다음 변환을 한 번만 수행하면됩니다. – HLGEM

1

CONCAT (TO_CHAR (ProcessIn.SCAN_TIME 'mm') TO_CHAR (ProcessIn.SCAN_TIME) 'dd는') = CONCAT (TO_CHAR (ProcessDefect.SCAN_TIME 'mm'를 단순화하는 다른 방법) , TO_CHAR

뭔가

같은

TO_CHAR (ProcessIn.SCAN_TIME, 'DDMM') = TO_CHAR (ProcessDefect.SCAN_TIME, 'DDMM')를 말하는 것이다) (ProcessDefect.SCAN_TIME, 'DD 형식').

은 ((기술 과정에 TO_CHAR를 인덱스 scan_time_idx를 만드는 기술 과정을 함수 기반 인덱스

을 만들 수있는 성능을 향상시킬 수 있도록 지원합니다.SCAN_TIME, 'ddmm')));

색인 ProcessIn에서 색인 scan_time_idx를 작성하십시오 (to_char (ProcessDefect.SCAN_TIME, 'ddmm')));

기능 기반 색인에 대한 자세한 내용은 http://www.akadia.com/services/ora_function_based_index_2.html 을 참조하십시오.

또는 to_char (tablename.SCAN_TIME, 'ddmm') 형식의 '데이터'테이블에서 monthday이라는 별도의 열에 scan_time을 저장하고 새 열의 색인을 생성 할 수 있습니다.

생성되면, 쿼리는 다음과 같을 것이다 : -

With ProcessIn as 
(
select Data.Scan_time, equipment.equipment_desc, data.serial_number,Data.monthday 

from Data, equipment 

where Data.equipment = equipment.equipm_barcode and data.quality_plan = 'N/A' and  data.error_code = 'N/A' 
) 

--Total process defects 
,ProcessDefect as 
(
select Data.Scan_time, equipment.equipment_desc, data.serial_number,Data.monthday 

from Data, equipment 

where Data.equipment = equipment.equipm_barcode and (data.quality_plan <> 'N/A' or   data.error_code <> 'N/A') 
) 

Select monthday as "Date", ProcessIn.equipment_desc,          count(ProcessIn.serial_number),  count(ProcessDefect.serial_number) 

from ProcessIn 
Left Join ProcessDefect 
On ProcessIn.monthday = ProcessDefect.monthday 
and ProcessIn.equipment_desc = ProcessDefect.equipment_desc 
group by ProcessIn.monthday, ProcessIn.equipment_desc 
; 
+0

'ProcessIn'과'ProcessDefect'는 테이블이 아닌 서브 쿼리를 포함하고 있기 때문에 실제로'create index scan_time_idx on Data (to_char (scan_time, 'ddmm'))'를 원할 것입니다. 그러나 실제식이 인덱싱 된 식과 정확하게 일치하지 않기 때문에이 쿼리를 실행하는 데 사용되지는 않을 것이라고 생각합니다. –

+0

아 그래, @Dave 코스타에 주목하지 않았다. 나는 그것이 기능 기반 인덱스가있는 테이블 데이터 여야한다는 데 동의한다. 그 이유는 잘 모르겠지만, 조인이 to_char (ProcessIn.SCAN_TIME, 'ddmm') = to_char (ProcessDefect.SCAN_TIME, 'ddmm')로 변경된 경우입니다. –

+0

새로운 제안을 추가하는 간단한 제안을 시도했습니다. to_char (tablename.SCAN_TIME, 'ddmm')가있는 열을 테스트했지만 불행히도이 점이 도움이되지는 않습니다. – AFJ