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

时间:2012-08-05 14:59:24

标签: sql-server performance sql-server-2008

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

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

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有大约1百万条记录,表cc1大约有700 000条。

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

我正在考虑创建一个索引视图,索引字段ft1.F5_CNUMSER和ft1.F5_CNUMDOC。我认为这会改善性能。我也希望你对这个问题有所了解,如果我在视图上创建了索引,那么查询表有可能在操作中被破坏,那些对于实际系统来说是非常重要的表。

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

2 个答案:

答案 0 :(得分:4)

看到你的两个表总共有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)
    

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

答案 1 :(得分:2)

当然,实现与索引视图的连接可能很有用,因为连接非常糟糕。索引对它无济于事。创建视图时,将F5_CGLOSA设为第一个聚簇索引列,以便查询可以在其上进行搜索。

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