Text子数据类型在where子句中表现不佳

时间:2012-03-21 14:29:40

标签: sql-server-2008 tsql

我有一个存储过程返回一些字段,其中大部分包含一些客户信息,然后还有一个字段包含文本数据类型字段中的xslfo“blob”。我正在尝试优化进程以忽略此text数据类型字段中没有值的记录,但是当我将其添加到where子句时:

And cl.CorrespondenceFO IS NOT NULL
And Convert(varchar(1), cl.CorrespondenceFO) <> ''

查询超时。我意识到文本数据类型已被弃用,因此我将来需要转换该列,但我需要在此之前对其进行优化。是否有任何建议如何让这个存储过程返回带有这两个额外where子句的结果? TIA

编辑:我已将数据类型更新为varchar(max)并尝试了下面的所有建议,但查询仍然是超时的。还有其他建议吗?

5 个答案:

答案 0 :(得分:4)

  1. 立即转换为varchar(max)
  2. 通过禁止带有CHECK约束的空字符串
  3. 来修复写入数据
  4. 仅使用WHERE ... cl.CorrespondenceFO IS NOT NULL
  5. 我无法测试,但IS NOT NULL检查应该使用NULL位图

    或者,使用带有LEN(或DATALENGTH用于文本)的计算列并对其进行索引/过滤。

答案 1 :(得分:3)

为什么还在使用TEXT?这应该是VARCHAR(MAX)。而不是您的查询,为什么不:

WHERE DATALENGTH(cl.CorrespondenceFO) > 0;

(虽然我同意@gbn - 你不应该允许空字符串,如果它对你来说和NULL一样。)

答案 2 :(得分:1)

转换为VARCHAR听起来效率不高,您确定cl.CorrespondenceFO IS NOT NULL不足以过滤空blob的行吗?

如果真的不够,可以使用DATALENGTH来避免转换:

And cl.CorrespondenceFO IS NOT NULL
And DATALENGTH(cl.CorrespondenceFO) > 0

答案 3 :(得分:0)

我不熟悉SQL Server,但如果它的文本类型与MySQL / PostGres文本类型类似,那么效率会很低。这些类型存储在表外,因此实际行只包含指向实际文本blob的指针。这意味着大量的磁盘搜索,索引对你不会有好处等等。

答案 4 :(得分:0)

我终于开始工作了。在将我的旧text,ntext和image数据类型转换为varchar(max),nvarchar(max)和varbinary(max)的建议之后,查询仍然超时。所以这是有效的解决方案。

旧版本= 选择FieldA,FieldB 来自TableA FieldA In的位置('value1','value2') 和Len(FieldB)&gt; 0 - 这是不起作用的

新版本=      创建表#temp (     FieldA varchar(10),     FieldB varchar(最大) )

插入#temp (     FIELDA,     FieldB ) 选择FieldA,FieldB 来自TableA FieldA In('value1','value2')

选择* 来自#temp Len(FieldB)&gt; 0

Drop Table #temp

(我不确定为什么我的格式化不起作用,抱歉)

出于某种原因,当我尝试在原始查询中执行Len()检查时,查询总是超时(可能与表大于1700万条记录有关),所以只生成一个子集要处理的记录,然后检查该子集的Len()允许我及时获取我的记录。

全部谢谢!