【发布时间】:2015-09-23 20:42:28
【问题描述】:
-- Holds last 30 valdates
create table #valdates(
date int
)
insert into #valdates
select distinct top (30) valuation_date
from tbsm.tbl_key_rates_summary
where valuation_date <= 20150529
order by valuation_date desc
select
sum(fv_change), sc_group, valuation_date
from
(select *
from tbsm.tbl_security_scorecards_summary
where valuation_date in (select date from #valdates)) as fact
join
(select *
from tbsm.tbl_security_classification
where sc_book = 'UC' ) as dim on fact.classification_id = dim.classification_id
group by
valuation_date, sc_group
drop table #valdates
这个查询大约需要 40 秒才能返回,因为事实表有将近 1300 万行。我可以对此做些什么吗?
【问题讨论】:
-
附带说明,如果您只保存 30 个值,我将在内存中创建一个临时表 -->DECLARE TABLE @valdates{...}。全部在内存中,以后不用担心删除,当存储过程或sql命令失去作用域时会自动删除。
-
表变量不是“全部在内存中”,它们也像临时表一样存储在 tempdb 中,并且由于缺少统计信息/估计的行数为 1,可能会导致更大的问题。正常的临时表被删除程序结束时也是如此。
-
在将声明@tmp 表切换为创建#tmp 表时,我们实际上大大提高了性能。临时表保存的数据越大,性能提升就越大。我会试试你的小费,谢谢。
-
@Allen,您应该至少包含一些关于表和索引是什么的想法,并且可能还包括此选择的查询计划。我的猜测是您有评估日期的索引,但它是否也包含 fv_change,或者是否进行了关键查找以找到该索引和/或分类 ID?
-
@Jamez,事实表包含 fv_change、valuation_date。 dim 表包含 sc_book、sc_group。我们按 sc_book 过滤并按 sc_group 聚合。分类 ID 连接两个表。不幸的是,这两个表的索引基本上都是伪造的。此外,valuation_date 未编入索引 :(
标签: sql-server performance join optimization