我有一个存储过程返回一些字段,其中大部分包含一些客户信息,然后还有一个字段包含文本数据类型字段中的xslfo“blob”。我正在尝试优化进程以忽略此text数据类型字段中没有值的记录,但是当我将其添加到where子句时:
And cl.CorrespondenceFO IS NOT NULL
And Convert(varchar(1), cl.CorrespondenceFO) <> ''
查询超时。我意识到文本数据类型已被弃用,因此我将来需要转换该列,但我需要在此之前对其进行优化。是否有任何建议如何让这个存储过程返回带有这两个额外where子句的结果? TIA
编辑:我已将数据类型更新为varchar(max)并尝试了下面的所有建议,但查询仍然是超时的。还有其他建议吗?
答案 0 :(得分:4)
varchar(max)
WHERE ... cl.CorrespondenceFO IS NOT NULL
我无法测试,但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()允许我及时获取我的记录。
全部谢谢!