具有大量子串性能的SQL Server查询

时间:2014-04-09 07:33:43

标签: sql-server tsql foxpro visual-foxpro

我有一个存储过程,我在其中执行批量插入到临时表中并在其字段上执行子字符串以获取主表所需的不同行。 没有。主表的列数为66,每次运行sp后添加的行大约为5500。 批量插入部件代码:

    CREATE TABLE [dbo].[#TestData] (
    logdate DATETIME,
    id CHAR(15),
    value VARCHAR(max)
    )

BEGIN TRANSACTION

DECLARE @sql VARCHAR(max)

SET @sql = 'BULK INSERT [dbo].[#TestData] FROM ''' + @pfile + ''' WITH (
    firstrow = 2,
    fieldterminator = ''\t'',
    rowterminator = ''\n''
    )'

EXEC(@sql)

IF (@@ERROR <> 0)
BEGIN
    ROLLBACK TRANSACTION

    RETURN 1
END

COMMIT TRANSACTION

子串部分的代码:

CASE 
        WHEN (PATINDEX('%status="%', value) > 0)
            THEN (nullif(SUBSTRING(value, (PATINDEX('%status="%', value) + 8), (CHARINDEX('"', value, (PATINDEX('%status="%', value) + 8)) - (PATINDEX('%status="%', value) + 8))), ''))
        ELSE NULL
        END,

此子字符串代码用于插入到所有66列中,并且类似于所有66列。 执行sp需要大约20-25秒。我试过对临时表进行索引,下载外键,下载所有索引,下载主键但仍需要相同的时间。 所以我的问题是可以提高性能吗?

编辑:界面应用程序是visual foxpro 6.0。 因为sql server很慢,有字符串操作,现在在foxpro上进行所有字符串操作。 foxpro新手任何建议如何从foxpro发送null到sqlserver? 从未在foxpro 6.0中使用null。

2 个答案:

答案 0 :(得分:2)

由于您实际上并未真正利用PATINDEX()的功能,因此您可能需要检查CHARINDEX() 的用法,尽管它的名称可以在字符串上运行,不仅仅是角色。 CHARINDEX()可能比PATINDEX()更快,因为它的功能稍微简单一些。

索引不会帮助您完成这些字符串操作,因为您没有搜索字符串的前缀。

您应该查看选项以避免在语句中过度使用PATINDEX()CHARINDEX();在处理的每个记录的66列中每个CASE中最多可以有4个(!)调用。

为此,您可能希望将字符串操作拆分为多个语句,以预先计算感兴趣的子字符串的起始和结束索引的值,例如

UPDATE temptable
SET value_start_index = CHARINDEX('status="', value) + 8

UPDATE temptable
SET value_end_index = CHARINDEX('"', value, value_start_index)
WHERE value_start_index >= 8

UPDATE temptable
SET value_str = SUBSTRING(value, value_start_index, value_end_index - value_start_index)
WHERE value_end_index IS NOT NULL

答案 1 :(得分:0)

SQL Server处理字符串的速度相当慢。对于此执行次数,最好使用SQL CLR用户定义的函数。除此之外你没有什么可以做的。