代码之家  ›  专栏  ›  技术社区  ›  Paulo Santos

如何用图像字段提高SQL Server表的性能?

  •  6
  • Paulo Santos  · 技术社区  · 14 年前

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

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

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

    此表当前有22K+行,甚至一个这样的简单查询:

    SELECT TOP 100 *
      FROM OFFENDING_TABLE
    

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

    我正在考虑将兼容性更新到SQL 2005(有一次我被告知应用程序可以处理它)。

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

    我正在考虑的另一件事是 sp_tableoption 设置 large value types out of row 1 就像现在一样 0 但我没有任何信息表明这样做是否会提高性能。

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


    编辑以澄清

    我的问题是,我无法控制应用程序向SQL Server请求什么,我对它做了一些思考(应用程序是.NET 1.1网站),它对一些我不知道是什么的内部内容使用了冒犯字段。

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

    4 回复  |  直到 14 年前
        1
  •  4
  •   Remus Rusanu    14 年前

    我建议您查看有问题的表布局运行状况:

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

    同样需要注意的是,avg_碎片\以百分比表示,page_计数,avg_page_空间\以百分比表示,record_计数和ghost_记录\计数。高碎片、大量虚影记录或低页面使用率等提示表示问题,只要从头重建索引(即表),就可以大大改善问题:

    ALTER INDEX ALL ON offending_table REBUILD;
    

    我这么说是因为你不能改变表格和应用程序。如果您能够更改表和应用程序,那么您已经得到的建议是好的建议(不要使用“*”,不要选择不带条件,使用更新的varbinary(max)类型等)。

    我还将研究性能计数器中的平均页面寿命,以了解系统是否内存不足。从您对症状的描述来看,系统看起来是IO绑定的,这让我认为正在进行的页面缓存很少,更多的RAM可以帮助,以及更快的IO子系统。在一个SQL2008系统上,我也建议打开页面压缩,但在2005年,您不能。
    而且,要确保查询不会被应用程序本身的争用阻塞,也就是说,查询不会花费30秒中的90%等待行锁。看 sys.dm_exec_requests 当查询正在运行时,请查看等待时间、等待类型和等待资源。是pageiolatch-xx吗?还是锁?另外,如何 sys.dm_os_wait_stats 在服务器中,最重要的等待原因是什么?

        2
  •  2
  •   marc_s Hady Salah    14 年前

    首先- 永远不要做 SELECT * 在生产代码中-是否报告。

    您有三个基本选择:

    • 如果不总是需要这个blob字段,请将它移到一个单独的表中;可能不实际,因为您提到不能更改模式。

    • 小心你的 SELECT 语句只选择您真正需要的字段-并省略blob字段

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

    没有什么神奇的“让这个更快”切换——但是您可以优化您的查询或优化您的表布局。两者都有帮助。如果您不能更改任何内容——既不能更改表布局,也不能添加索引,也不能更改查询,那么您将很难优化任何内容,恐怕……

    只将字段更改为varbinary(max)根本不会更改任何内容-仅更改数据类型就不会提高性能。

        3
  •  1
  •   MartW    14 年前

    简短的回答是,当返回的字段不包括有问题的图像字段时,仅针对多行进行Do选择,即不选择*。如果需要图像字段的值,请逐个检索。

        4
  •  0
  •   Ray    14 年前

    设置大值类型行外选项绝对有助于提高性能。行大小将显著减小,SQL Server可以做更少的物理读取来访问表。