代码之家  ›  专栏  ›  技术社区  ›  DHornpout

使用varchar(max)列从SQLServer表中获取所有数据的最有效方法

  •  1
  • DHornpout  · 技术社区  · 15 年前

    此问题适用于SQL Server 2005。

    Table_A
        Id Guid (PrimaryKey)
        TextContent varchar(max)
    

    该表包含约7000条记录,文本内容范围从0到150K+。

    当我执行select语句时 从表A中选择Id、文本内容 ,花了很长时间,大约10分钟。

    在主执行期间,我仅加载某些记录。例子: 从Id所在的表格A中选择Id,TextContent(@id0、@id1、@id2、@id3….@id20) . 这个查询不是很慢,但也不是很快。我想看看是否可以通过在运行时之前提取文本内容来优化流程。这个过程可以在一两分钟内运行,但10分钟是不可接受的。

    6 回复  |  直到 15 年前
        1
  •  2
  •   Andrew    15 年前

    GUID是主键,默认情况下也是您的群集键,这无疑会导致较大的碎片化-但鉴于列的性质,varchar(max)将在LOB存储中定期处于页外状态,而不会存储在页上,除非它符合8060限制。

    因此,如果将GUID作为主GUID进行集群化,则不会对碎片化有所帮助-您可以使用DMV sys.dm_db_index_physical_stats检查碎片化级别

    我不认为碎片是真正的问题,除非每行的平均数据量很高,例如经常超过8k。

    除此之外,te GUID可能是群集键,因此它甚至无法扫描数据页而不移动大量磁盘头。

    我知道您希望预缓存数据,这有时可以工作,但它是在这样一个大的实体上执行的,它往往表明有其他错误,您正在修复错误的问题。

    A.

        2
  •  1
  •   Philip Kelley    15 年前

    也许您想要的只是从表中检索一些数据?

        3
  •  1
  •   Erich    15 年前

    这是从表中获取数据的正确方法,除非您只需要一行。如果只需要一行,只需使用正确的查询即可。

    您使用的是哪种网络连接?这么说吧,你有7000条记录。每个都包含平均100k的数据(为了方便起见,如果数据大于或小于此值,那很好,我的观点仍然有效)。总查询将返回700 MB的数据!即使通过极快的连接,也可以轻松地获得10分钟的下载时间。

    即使在完美的100兆连接下,传输也需要将近一分钟!此外,您还必须从物理磁盘获取数据,这还需要一段时间。

    我建议进行某种分页,以便以较小的比特获取数据。

        4
  •  1
  •   Rob Garrison    15 年前

    您的Id列是一个GUID。您是否使用默认值?是NewID()吗?我想它是聚集在PK上的。

    如果您使用NewSequentialID()作为默认值,您将获得更少的页面拆分,因此您的数据将分布在更少的物理页面上。

    有了这么多的数据,这是我能看到的唯一有助于提高性能的东西。

        5
  •  0
  •   svens    15 年前

    正如许多其他人提到的,您正在获取大量数据。首先确定是否需要所有行。

    如果您这样做了,不要一次获取所有内容,而是使用LIMIT。这实际上会降低速度,但如果出现任何故障,您只需再次加载一小段,而不必再等待10分钟。

    SELECT Id, TextContent FROM Table_A LIMIT 0, 30
    

    此查询将获取表的前30个条目。具有

    SELECT Id, TextContent FROM Table_A LIMIT 30, 30
    

        6
  •  -2
  •   JonH    15 年前

    1) 不要使用SELECT*选项,始终列出您的列,无论是1、2还是100

    15万字?在那个领域?这就是你所指的吗?