7

我在工作中遇到了一个非常特殊的性能问题!

在我们使用的系统中,有一个表格,其中包含有关当前工作流程的信息。其中一个字段包含一个电子表格,其中包含有关该过程的元数据(不要问我为什么!不,我不能改变它!!)

问题是该电子表格存储在 SQL Server 2005 的 IMAGE 字段中(在与 SQL 2000 兼容的数据库集中)。

该表目前有 22K+ 行,甚至是这样的简单查询:

SELECT TOP 100 *
  FROM OFFENDING_TABLE

在查询分析器中检索数据需要 30 秒。

我正在考虑更新对 SQL 2005 的兼容性(一旦我被告知该应用程序可以处理它)。

我在想的第二件事是将列的数据类型更改为,varbinary(max)但我不知道这样做是否会影响应用程序。

我正在考虑的另一件事是使用sp_tableoption将 设置large value types out of row1当前0,但我不知道这样做是否会提高性能。

有谁知道如何在这种情况下提高性能?


编辑澄清

我的问题是我无法控制应用程序向 SQL Server 提出的要求,并且我对它进行了一些反思(该应用程序是一个 .NET 1.1 网站)并且它使用了一些我不知道的内部内容的违规字段这是什么。

我需要提高这张表的整体性能。

4

4 回答 4

4

我建议您查看有问题的表格布局健康状况:

select * from sys.dm_db_index_physical_stats(
       db_id(), object_id('offending_table'), null, null, detailed);

需要寻找的还有 avg_fragmentation_in_percent、page_count、avg_page_space_used_in_percent、record_count 和 ghost_record_count。高碎片化、大量幽灵记录或低页面使用百分比等线索表明存在问题,只需从头开始重建索引(即表),事情就可以得到很大改善:

ALTER INDEX ALL ON offending_table REBUILD;

考虑到您无法更改表格或应用程序,我这么说。如果您能够更改表格和应用程序,那么您已经获得的建议是很好的建议(不要使用'*',不要选择 w/oa 条件,使用较新的 varbinary(max) 类型等) .

我还会查看性能计数器中的平均页面生命周期,以了解系统是否内存不足。从您对症状的描述来看,系统看起来受 IO 限制,这使我认为页面缓存很少,更多的 RAM 以及更快的 IO 子系统可能会有所帮助。在 SQL 2008 系统上,我还建议打开页面压缩,但在 2005 上你不能。
而且,为了确定,请确保查询不会被应用程序本身的争用阻止,即。查询不会花费 30 秒的 90% 来等待行锁。在查询运行时查看sys.dm_exec_requests,查看 wait_time、wait_type 和 wait_resource。是 PAGEIOLATCH_XX 吗?或者它是一把锁?另外,sys.dm_os_wait_stats怎么样在您的服务器中,最重要的等待原因是什么?

于 2010-02-12T18:14:01.483 回答
2

首先-永远不要SELECT *在生产代码中执行-报告与否。

您有三个基本选择:

  • 如果不总是需要,将该 blob 字段移到单独的表中;可能不实用,因为您提到您无法更改架构

  • 对您的陈述更加小心,SELECT以仅选择您真正需要的那些字段 - 并省略 blob 字段

  • 看看您是否可以限制您的查询以包含一个WHERE子句并找到一种方法来优化查询计划,例如通过向表中添加合适的索引(如果可以的话)

没有神奇的“让这个更快”的开关 - 但您可以优化您的查询或优化您的表格布局。两者都有帮助。如果您无法更改任何内容 - 表格布局、添加索引或更改查询,您将很难优化任何内容,恐怕......

仅将字段更改为 VARBINARY(MAX) 根本不会改变任何内容 - 仅通过更改数据类型不会预期性能提升。

于 2010-02-12T17:26:38.517 回答
1

一个简短的回答是,当返回的字段不包括有问题的图像字段时,只对多行执行 SELECT,即没有 SELECT *。如果您想要图像字段的值,请根据具体情况进行检索。

于 2010-02-12T17:10:18.573 回答
0

将大值类型设置为行外选项肯定会有助于提高性能。行大小将显着减小,SQL Server 可以执行更少的物理读取来通过表。

于 2010-02-12T17:12:04.673 回答