2013-04-17 2 views
0

저는 사용자 선택에 따라 쿼리가 연결되어 DB2 데이터베이스로 시작되는 방문 페이지에 대해 여러 SQL 쿼리를 최적화하려고했습니다. 모든 것이 거의 잘 돌아가고 있으며 많은 쿼리가 1 초 또는 1 초에 가까워지고 있습니다. 성능 테스트로서, 우리는 최근 테스트 데이터베이스에 트럭 데이터를로드했습니다. 하나의 테이블에 약 20 배가 곱해 졌는데 40k 정도에서 750k 레코드로 증가했습니다. 우리는 1 년 정도의 데이터 양에 대한 대략적인 시뮬레이션을 원했습니다. 일부 쿼리는 이후 변경되었지만 특히 한 그룹은 엄청난 히트를 기록했습니다.이 테이블은 750k 레코드가있는 테이블입니다. 쿼리 자체에는 여러 가지 조인이 있지만 단일 테이블에서 선택/필터링하기 위해 잘라내는 것이 여전히 30 초 이상 걸리는 것으로 나타났습니다. 때로는 쿼리 자체가 오래 걸리고 때로는 쿼리가 몇 초 안에 실행되고 행을 가져 오는 것은 20 초 이상 동안 느리게 진행됩니다.SQL 쿼리가 결과 집합을 가져 오는 데 어리석은 시간을 보냄

쿼리 자체는 테이블에서 약 12 ​​개의 열을 선택하고 몇 가지 기준으로 필터링합니다. 원격으로 빠르게 수행 할 수있는 유일한 방법은 필터링 기준을 엄격히 줄여 필터링을 크게 단순화하거나 행 수를 대폭 줄이는 것입니다. 그런 식으로 몇 초안에 실행되지만 복잡한 정도에 따라 계층화하면 실행이 미친 것처럼 지연됩니다. 설명 계획은 도움이되지 않습니다. 100K 미만의 경우처럼 런타임보다 훨씬 낮은 비용을 보여줍니다. 이 숫자를 사용하면 2 초 미만으로 잘 돌아갈 것입니다.

인덱스가 준비되어 있지만 나쁜 인덱스가 실제로 숨 막히는 지 궁금합니다.

SELECT 
--12 or so fields 
FROM 
TABLE A 
--A few joins 
WHERE 
A.FIELD1 is not null 
AND a.FIELD2 IN (:param) --max 2 values here 
AND (a.FIELD3 BETWEEN :date1 AND date2 
(OR A.FIELD3 < :date3 AND A.FIELD4 IN ('ONE','TWO'))) 

... 쿼리 구조의 아이디어를 얻으려면 이미 단지 매우 간단한 쿼리에 도움을 준 OR 절에서 비트를 만지작 제거했습니다. 그렇지 않으면 런타임이 여전히 길어서 차이를 만들 수 없습니다. Runstats/distributed statistics는 정확합니다. 테이블이 방금 도움없이 다시 통근했습니다. 나는 누군가가 여기에 약간의 포인터를 가지고 있기를 바라고있다.

업데이트 : 분산 통계가 실행되었습니다. SYSIBM.SYSCOLDIST 및 SYSCAT.COLDIST는 모두 표 A에 대한 현재 자료를 표시합니다. 조회는 계속해서 무시 무시하게 실행되고 결과를 영원히 가져옵니다. 더 나은 점은 차이가있을 수 있지만 의미가있을만큼 충분하지는 않습니다. 작은 결과 집합을 반환하도록 필터를 조정하는 것이 매우 빠르게 실행된다는 점은 주목할 가치가 있습니다. 큰 필터를 반환하도록 필터를 변경하면 행을 페치하는 데 오래 걸립니다. 몇 안되는 내부 조인은 런타임을 망쳐 놓는 것처럼 보이지 않지만, 멀리 있거나 커다란 것은 무엇이든지 그것을 완전히 날려 버린다. 이 동작을 나타내는 유일한 테이블입니다. 이보다 더 빠르게 실행되는 270 만 개의 행을 가진 다른 사람들이 있습니다.

나는 문제를 발견했다고 생각합니다. 데이터로드가 해당 날짜를 일주일 범위에 넣었으므로이 범위를 터치해도 데이터 행이 수십만 행까지 날아갈 것입니다. 범죄. 해당 범위의 날짜를 잡아서 1 년 동안 더 나은 배포로 행을 업데이트하는 스크립트 시간 ...

Aaaand 완전히 문제는 아니 었습니다. 데이터로드 전에 날짜 범위를 넓은 영역으로 설정하면 약 4.5k 개의 결과가 표시되지만 결과 집합을 가져 오는 데는 약 9 초, 3.5 초가 소요됩니다.

+0

사람들이이 문제를 해결하도록 돕고 싶다면 '- 몇 개의 조인'을 설명해야합니다. 이러한 조인은 사용자의 성능에 중요한 영향을 미칩니다. –

+0

조인을 제거해도 쿼리가 더 빠르게 수행되지는 않습니다. 단일 테이블 및 필터 조건만으로도 30 초 이상 걸릴 수 있습니다. 조인으로 ... 잠깐. 그러나 문제의 근본 원인은 분명히 TABLE A입니다. – user1017413

+0

어떤 DB2 제품군 구성원을 사용하고 있습니까? i, LUW 또는 z/OS 용 DB2는 무엇입니까? – WarrenT

답변

0

UNION으로 사용해 보셨습니까? 중복을 표시하려면 UNION ALL을 사용할 수 있습니다.

SELECT --12 or so fields 
FROM TABLE A 
--A few joins 
WHERE A.FIELD1 is not null 
AND a.FIELD2 IN (:param) --max 2 values here 
AND a.FIELD3 BETWEEN :date1 AND date2 
UNION 
SELECT --12 or so fields 
FROM TABLE A 
--A few joins 
WHERE A.FIELD1 is not null 
AND a.FIELD2 IN (:param) --max 2 values here 
AND A.FIELD3 < :date3 
AND A.FIELD4 IN ('ONE','TWO') 

더 빠른 속도가 아니라면 EXPLAIN 계획을 게시 할 수 있습니까?

0

오래된 통계가 종종 느린 쿼리의 원인입니다. 특히 누락 된 인덱스가 문제가되지 않는 경우가 많습니다.

"저렴한"비용의 explain 계획도이를 지원합니다.

방금 ​​방대한 양의 데이터를 삽입했다는 사실은 매우 그럴듯한 원인입니다.

+0

그럼 내가있을거야. 데이터로드 후에 RUNSTATS가 완료된 것처럼 보이지만 완료되었다고 생각되는 분배 통계는 표시되지 않습니다. 그 데이터를 수집하고 차이가 있는지 확인해 보겠습니다. – user1017413

+0

@ user1017413 : 문제의 해결책을 찾았습니까? –

+0

DBA를 기다리면서 곧 알게 될 것입니다. 날짜 범위는 분명히 그 부분 이었지만 데이터 정렬 이전에 문제가되지 않은 OR 절이라고 생각합니다. – user1017413

관련 문제