在 sql server 2008 中对百万记录表进行简单但缓慢的查询

Posted

技术标签:

【中文标题】在 sql server 2008 中对百万记录表进行简单但缓慢的查询【英文标题】:Simple but slow query on million records table in sql server 2008 【发布时间】:2012-08-05 14:59:23 【问题描述】:

朋友们好,提前感谢您的帮助。

我正在执行一个在两个表之间执行连接的简单查询:

SELECT
F5_CNOMBRE,
F5_CTD,
F5_CNUMSER,
F5_CNUMDOC,
F5_DFECDOC,
F5_NIMPORT,
CD_DFECCAN,
CD_CCODART
FROM ft1
INNER JOIN cc1
ON RTRIM(cc1.CD_CNRODOC) = RTRIM(ft1.F5_CNUMSER) + ft1.F5_CNUMDOC
WHERE F5_CGLOSA LIKE @varNroExpediente + '%'

表 ft1 大约有 100 万条记录,表 cc1 大约有 70 万条记录。

当没有人在/使用这些表时,查询运行速度很快,但是当用户使用它们时,查询大约需要 30/50 秒才能完成。

我正在考虑创建一个索引视图,索引字段 ft1.F5_CNUMSER 和 ft1.F5_CNUMDOC。我认为这会提高性能。我也想听听你对这个问题的看法,如果我在视图上创建索引,查询的表是否有可能在操作中被损坏,这些表对于实际系统来说是非常重要的。

我很欣赏我能在这个主题上获得的洞察力。

【问题讨论】:

CD_CNRODOCF5_CNUMSER 是否有充分的理由在数据库中不被修剪? ft1 上是否有包含 F5_CNUMSER(已修剪)和 F5_CNUMDOC 的索引? (即一个索引有两列。)索引统计信息是最新的吗? @HABO 不幸的是,这些修剪是必要的,因为某些数据包含空白。该表没有活动索引,因此在我的理解中没有活动索引统计信息。 您选择的那 8 列是否只选择了这两个表的一小部分列?还是他们几乎占了整个桌子? @marc_s ft1 表有 90 列,cc1 有 57 列 【参考方案1】:

看到您的两个表总共有 147 列,但您“只”选择了其中的 8 个(一件好事!),通过在您的表上设置两个索引,您可能会获得良好的性能提升:

在表ft1 上,在F5_CGLOSA(您在WHERE 子句中使用)创建索引并包含该表中的其他列:

CREATE INDEX IX01_ft1 
ON dbo.ft1 (F5_CGLOSA)
INCLUDE(F5_CNOMBRE, F5_CTD, F5_CNUMSER, F5_CNUMDOC, F5_DFECDOC, F5_NIMPORT)

在另一张表cc1 上,在两列中较小的列上创建索引(取决于它们的数据类型)并包含另一列 - 我只是“猜测”它可能是这样的:

CREATE INDEX IX01_ft1 
ON dbo.cc1(CD_DFECCAN)
INCLUDE(CD_CCODART)

这样,您的查询(它需要的所有列)被这两个索引“覆盖”,并且能够只扫描这两个索引(并结合这些扫描的结果),而不必扫描整个表(更大、更多的列)可以带来显着的改进(希望如此!)。

【讨论】:

谢谢,我可以在视图上创建索引而不是在表上创建索引吗?我没有表修改权限。顺便说一句,Glosa 字段不是唯一字段(是 cmets 字段)。 @CoderRoller:不,您不能在视图上创建索引 - 除非您已将其设为 indexed 视图(在该视图上创建了聚集索引)。另外:F5_CGLOSA 不需要是唯一的 - 它只是被索引,仅此而已【参考方案2】:

当然,用索引视图实现连接可能很有用,因为连接非常讨厌。索引对此无能为力。创建视图时,将 F5_CGLOSA 设为第一个聚集索引列,以便您的查询可以对其进行查找。

不确定这对您来说是否可行,但您能否 a) 更改连接列,这样您就不必加入函数结果并成为 SARGable 并且 b) 找出该查询的并发用户导致阻塞的原因?也许你可以通过打开快照隔离来解决这个问题。

【讨论】:

谢谢,我认为没有办法改变连接,但我也在考虑添加隔离,我会尝试看看它在生产中的表现。如果我为查询添加索引视图,在其上设置的索引可能会损坏表? 除了写入速度稍慢并且某些模式操作不再可能(例如,重命名视图中的列)之外,您不会造成任何伤害。

以上是关于在 sql server 2008 中对百万记录表进行简单但缓慢的查询的主要内容,如果未能解决你的问题,请参考以下文章

如何使用python对百万行数据进行ETL?

43 RocketMQ对百万消息积压问题的处理方案

SQL Server 百万级数据提高查询速度的方法(转)

如何在 SQL Server 中更新具有数百万行的大表?

如何利用php数组对百万数据进行排重

SQL Server 2008 中的错误日志记录