我无法在Sybase 15.5上优化以下查询。有谁知道我怎么能改善它。在那里使用的每个表都有大约3000万行。我尽力优化它,但仍然耗费大量时间(1.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)
我怀疑它是一个工会问题。查询是更可能的麻烦制造者。
我想你应该从临时表上添加索引开始:
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 )
...
另外,我认为在#tmp1,#tmp2中使用它们的方式没什么意义。你可以改为调用CTE。也。我建议你尝试使用PARTITION BY而不是GROUP BY语句。
答案 1 :(得分: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
答案 2 :(得分:0)
每个临时表中最多有多少行? 看起来临时表可以使用HAVING替换,我需要测试它,当你的group by在一个列上并且输出中需要更多列时,它总是很复杂。
尝试使用SET STATISTICS PLANCOST ON和SET STATISTICS IO ON运行此语句,因为这样可以很好地了解扫描的页数以及Sybase在优化查询时是否出错。