使用NText列的Count(*)非常非常慢。为什么这么慢?我怎样才能提高性能?

时间:2011-01-12 11:32:19

标签: sql database sql-server-2005 tsql

我的SQL Server 2005数据库出现了一些问题。我有一个包含订单行的表,每行都有一个名为NTEXT的{​​{1}}字段。我想计算所有没有信息存储在其中的字段。我正在使用此查询:

XmlData

该表有230.314条记录,这个计数查询需要几分钟。你们中的任何人都知道如何提高性能吗?

注意:我无法将列的类型更改为SELECT Count(*) FROM [OrderLine] WITH(NOLOCK) WHERE [XmlData] NOT LIKE '' AND [XmlData] IS NOT NULL 类型。 NOLOCK是一位同事的小费。

我期待着一些提示和解释。

3 个答案:

答案 0 :(得分:4)

为了避免昂贵的LOB读取,将[XmlData] NOT LIKE ''替换为DATALENGTH([XmlData])>0 - DATALENGTH不需要读取每行的LOB值。

另外,正如其他人所建议的那样:如果可能的话,使用nvarchar(max)而不是ntext。

答案 1 :(得分:2)

不推荐使用NTEXT,改为使用nvarchar(max)(考虑使用xml ...)。

如果更改列类型,则可以在列上创建索引,因此为列创建统计信息将有助于SQL选择使用此索引的最佳方式。

为XMLData列创建统计信息,因为这会创建一个值的映射,这将大大增加查询的计数类型。

CREATE STATISTICS STATOrderLineXmlData
ON OrderLine (XmlData)
WITH FULLSCAN

根据@ Pent的回答,您应该更改此查询: 替换此查询:

SELECT Count(*) 
FROM [OrderLine] WITH(NOLOCK) 
WHERE [XmlData] IS NOT NULL 
AND DATALENGTH([XmlData]) > 0

如果您要更改nvarchar(max)的列类型,请检查this Link。 链接有关于在列更改后您必须做的一些棘手的更新信息。

答案 2 :(得分:1)

首先,此查询将涉及表扫描。这将是230K行的慢速。您可以尝试用长度(XmlData)= 0替换NOT LIKE,但我认为这不会有太大帮助。另一方面,我不确定Length函数是否适用于NText数据类型。我不这么认为,现在我想起来了。

底线是表扫描很慢,处理NText数据类型很慢。所以你在这里有一个糟糕的组合。除非可以更改数据类型,否则我认为这里没有太大的改进空间。

而且,我确信您可能会意识到使用WITH NOLOCK存在读取脏数据的风险?是的它可以帮助表现,但它不是免费的。您可能正在阅读未提交的更改。