2014-04-17 5 views
2

Sybase 15.5에서 다음 쿼리를 최적화하는 데 문제가 있습니다. 아무도 내가 그것을 향상시킬 수있는 방법을 알고 있습니까. 거기에 사용 된 테이블에는 각각 약 3 천만 개의 행이 있습니다. 나는 그것을 최적화하기 위해 최선을 다했지만 여전히 많은 시간을 보냈다 (1.5 시간).Sybase 15.5 통합 쿼리 최적화

create table #tmp1(f_id smallint, a_date smalldatetime) 
create table #tmp2(f_id smallint, a_date smalldatetime) 


insert #tmp1 
select f_id, a_date = max(a_date) 
    FROM audit_table 
    WHERE i_date = @pIDate 
group by f_id 

insert #tmp2 
select f_id , a_date = max(a_date) 
    FROM n_audit_table 
    WHERE i_date = @pIDate 
group by f_id 

    create table #tmp(
    t_account varchar(32) not null, 
    t_id varchar(32) not null, 
    product varchar(64) null 
    ) 

insert into #tmp 
select t_account,t_id, product 
    FROM audit_table nt, #tmp1 a 
    WHERE i_date = @pIDate 
    and nt.a_date = a.a_date 
    and nt.f_id = a.f_id 
union 
select t_account,t_id, product 
    FROM n_audit_table t, #tmp2 a 
    WHERE t.item_date = @pIDate 
    and t.a_date = a.a_date 
    and t.f_id = a.f_id 

두 테이블 모두 i_date, a_date, f_id에 색인을 가지고 있습니다. 오랜 시간이 지난 곳에서 showplan을 찾으십시오. 상태 2 (24 행)에 대한 질의 계획. 내가 그 노동 조합의 문제가 의심 시리얼 모드

STEP 1 
    The type of query is INSERT. 

10 operator(s) under root 

    |ROOT:EMIT Operator (VA = 10) 
    | 
    | |INSERT Operator (VA = 9) 
    | | The update mode is direct. 
    | | 
    | | |HASH UNION Operator (VA = 8) has 2 children. 
    | | | Using Worktable1 for internal storage. 
    | | | Key Count: 3 
    | | | 
    | | | |NESTED LOOP JOIN Operator (VA = 3) (Join Type: Inner Join) 
    | | | | 
    | | | | |SCAN Operator (VA = 0) 
    | | | | | FROM TABLE 
    | | | | | #tmp1 
    | | | | | a 
    | | | | | Table Scan. 
    | | | | | Forward Scan. 
    | | | | | Positioning at start of table. 
    | | | | | Using I/O Size 2 Kbytes for data pages. 
    | | | | | With LRU Buffer Replacement Strategy for data pages. 
    | | | | 
    | | | | |RESTRICT Operator (VA = 2)(5)(0)(0)(0)(0) 
    | | | | | 
    | | | | | |SCAN Operator (VA = 1) 
    | | | | | | FROM TABLE 
    | | | | | | audit_table 
    | | | | | | nt 
    | | | | | | Index : IX_audit_table 
    | | | | | | Forward Scan. 
    | | | | | | Positioning by key. 
    | | | | | | Keys are: 
    | | | | | | i_date ASC 
    | | | | | | a_date ASC 
    | | | | | | Using I/O Size 2 Kbytes for index leaf pages. 
    | | | | | | With LRU Buffer Replacement Strategy for index leaf pages. 
    | | | | | | Using I/O Size 2 Kbytes for data pages. 
    | | | | | | With LRU Buffer Replacement Strategy for data pages. 
    | | | 
    | | | |NESTED LOOP JOIN Operator (VA = 7) (Join Type: Inner Join) 
    | | | | 
    | | | | |SCAN Operator (VA = 4) 
    | | | | | FROM TABLE 
    | | | | | #tmp2 
    | | | | | a 
    | | | | | Table Scan. 
    | | | | | Forward Scan. 
    | | | | | Positioning at start of table. 
    | | | | | Using I/O Size 2 Kbytes for data pages. 
    | | | | | With LRU Buffer Replacement Strategy for data pages. 
    | | | | 
    | | | | |RESTRICT Operator (VA = 6)(5)(0)(0)(0)(0) 
    | | | | | 
    | | | | | |SCAN Operator (VA = 5) 
    | | | | | | FROM TABLE 
    | | | | | | n_audit_table 
    | | | | | | t 
    | | | | | | Index : IX_n_audit_table 
    | | | | | | Forward Scan. 
    | | | | | | Positioning by key. 
    | | | | | | Keys are: 
    | | | | | | i_date ASC 
    | | | | | | a_date ASC 
    | | | | | | Using I/O Size 2 Kbytes for index leaf pages. 
    | | | | | | With LRU Buffer Replacement Strategy for index leaf pages. 
    | | | | | | Using I/O Size 2 Kbytes for data pages. 
    | | | | | | With LRU Buffer Replacement Strategy for data pages. 
    | | 
    | | TO TABLE 
    | | #tmp 
    | | Using I/O Size 2 Kbytes for data pages. 


Total estimated I/O cost for statement 2 (at line 24): 29322945. 
+0

쿼리 계획을 보았습니까? 비용이 가장 많이 드는 곳은 어디입니까? –

+0

노조를하는 동안 대부분의 비용이 발생합니다. 쇼 계획으로 내 쿼리를 업데이트했습니다. 좀 봐주세요. – user3545067

+0

이 쿼리에서 나를 도울 수있는 사람이 있습니까? – user3545067

답변

0

을 사용하여 최적화. 쿼리가 더 많은 트러블러입니다.

나는 당신이 당신의 임시 테이블에 인덱스를 추가하는 시작해야한다고 가정

create table #tmp1(f_id smallint, a_date smalldatetime) 
Create clustered index IX1Temp on #tmp1(f_id) 
Create clustered index IX2Temp on #tmp1(a_date) 
... 

또한, 나는 당신이 그들을 사용하는 방법 tmp2별로 #의 tmp1의 의미, #를 참조하십시오. 대신 CTE를 호출 할 수 있습니다. 또한. GROUP BY 대신 PARTITION BY를 사용하는 것이 좋습니다.

0

쿼리 실행 계획에 따르면 문제는 테이블이 임시 테이블을 검색한다는 것입니다.

insert into #tmp 
select t_account,t_id, product 
FROM 
    audit_table nt, 
    (
     select f_id, a_date = max(a_date) 
     FROM audit_table 
     WHERE i_date = @pIDate 
     group by f_id 
    ) a 
WHERE 
    i_date = @pIDate 
    and nt.a_date = a.a_date 
    and nt.f_id = a.f_id 
union 
select t_account,t_id, product 
FROM 
    n_audit_table t, 
    (
     select f_id , a_date = max(a_date) 
     FROM n_audit_table 
     WHERE i_date = @pIDate 
     group by f_id 
    ) a 
WHERE 
    t.item_date = @pIDate 
    and t.a_date = a.a_date 
    and t.f_id = a.f_id 
0

얼마나 많은 행 임시 테이블의 각 끝 :

다음 쿼리에 대한 실행 계획을 얻을하세요? 임시 테이블이 HAVING을 사용하여 대체 될 수있는 것처럼 보입니다. 테스트해야합니다. 그룹이 하나의 열에 있고 출력에 더 많은 열이 필요할 때 항상 복잡합니다.

이 문을 SET STATISTICS PLANCOST ON으로 설정하고 SET STATISTICS IO ON으로 설정하면 검사 할 페이지 수와 쿼리를 최적화하는 동안 Sybase가 잘못되어 있는지 잘 알 수 있습니다.