3

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

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

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 有大约 700 000 条记录。

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

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

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

4

2 回答 2

4

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

  • 在 table 上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)
    

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

于 2012-08-05T16:21:22.690 回答
2

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

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

于 2012-08-05T15:05:03.210 回答