【问题标题】:Improve query performance in 300 million rows table提高 3 亿行表的查询性能
【发布时间】:2019-04-17 05:12:00
【问题描述】:

我需要提高查询时间过长的性能。查询在源任务的 SSIS 数据流中使用。它是较长查询的一部分,但这就是导致问题的原因,因此我将其范围缩小如下:

select xa.*, s.idA 
from tableA s 
inner join tableB xa on s.idA = xa.idB
where xa.type = 'type_A'
  • TableA = 8000 万行
  • TableB = 3.4 亿行

TableAidA 上有一个非聚集索引,TableBidB 上有一个非聚集索引。执行计划使用TableA 的索引并对TableB 执行全表扫描,这需要98% 的工作量。我试图在TableB 的列idB 上创建一个非聚集索引,包括Type 列。我不得不在一小时后终止创建查询,因为它被 CXPACKET 等待类型挂起。可能它正在等待读取所有数据,但我的 SSIS 流不能浪费这么多时间的资源。然后我尝试在 tableB 列类型上创建一个聚集索引,我认为这会花费更少的时间。计划是使用这样的 cte 修改查询:

;with tmp as 
(
     select * 
     from tableB 
     where type = 'Type_A'
)
select xa.*, s.idA 
from tableA s 
inner join tmp xa on s.idA = xa.idB

使用此查询,我将在 tmp 表中只有 200k 行,并且我将避免全表扫描以利用所有可用索引过滤 tableB,因此我认为它将合理地提高速度

但是,我不得不终止创建查询,因为它需要超过 1 小时(再次暂停,再次 CXPACKET)。所以我的问题是:是否可以加快索引创建过程?是否可以估计创建索引所需的时间?

【问题讨论】:

  • 所以问题不在于改进查询,而在于如何在大表上创建索引? this 有帮助吗?
  • 我建议您使用 type = 'type_A' 创建一个 filtered 索引,因为这在您的查询中是硬编码的。如果过滤器是选择性的,它很可能会创建得更快,因为它必须加载更少的行。当然,它仍然必须首先找到它们

标签: sql performance sql-server-2008


【解决方案1】:

将条件移动到子查询 (CTE) 不是解决方案。您应该使用 SQL 来告诉 DBMS 要获取什么,而不是如何获取它。找到最佳计划是 DBMS 的任务。因此,请尽可能编写可读的查询,并通过提供适当的索引来帮助 DBMS。

您应该有以下查询索引:

create index idx1 on tableB ( type, idB ); -- to find B quickly and have the ID ready for the join
create index idx2 on tableA ( idA );

(你加入 idA = idB 看起来很奇怪,但我想这只是在示例中,对吧?)

【讨论】:

  • 嗯,他已经试过了。这个问题具有误导性。实际上他不能创建索引,因为表很大,一个小时后就停止了。在我看来,他只是需要更有耐心。
  • 谢谢你们。 Tim 的评论提供了一个链接,其中包含一些加快索引过程的建议。会试试的。这并不是缺乏耐心,由于索引创建需要 i/o,运行的数据流会变慢,并且一切都会退回。买不起,所以我想把它保持在一个小时左右。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 2013-08-03
  • 1970-01-01
  • 2017-03-14
  • 2021-08-03
相关资源
最近更新 更多