Sql server 具有大量子字符串的Sql server查询性能

Sql server 具有大量子字符串的Sql server查询性能,sql-server,tsql,foxpro,visual-foxpro,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 @s

我有一个存储过程,在该过程中,我对临时表执行大容量插入,并对其字段执行子字符串,以获得主表所需的不同行。 主表的列数为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
此子字符串代码用于insert into,与所有66列类似。 sp执行大约需要20-25秒。我尝试过在临时表上建立索引,删除外键,删除所有索引,删除主键,但仍然需要相同的时间。 所以我的问题是,性能是否可以提高

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

SQL Server在处理字符串方面相当慢。对于这种执行次数,最好使用SQL CLR用户定义函数。除此之外,您可以做的事情不多。

因为您没有真正利用
PATINDEX()
的功能,因此您可能需要检查的用法,而不是它的名称,它对字符串而不仅仅是字符进行操作
CHARINDEX()
可能比
PATINDEX()
更快,因为它是一个稍微简单一些的函数

索引对这些字符串操作没有帮助,因为您没有搜索字符串的前缀

您一定要研究一些选项,以避免在语句中过度使用
PATINDEX()
CHARINDEX()
;对于处理的每个记录中的66列,在您的
案例中最多有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

非常感谢。使用您的建议,将所有patindex替换为charindex。性能提高了几秒,现在需要约15-20秒。sql server似乎讨厌字符串操作:)VFP中的null有什么问题?它支持空值,您可以使用与T-SQL.Edited中相同的方法处理它们。想知道是否可以从Foxpro向sql server传递null,我将在周末尝试签入,但您也提到了使用VFP6。但是您的数据在SQL Server中吗?它来自哪里——一个VFP表?CSV文件?什么。。。此外,如果您可以显示主键的示例、66列中的某些列和示例数据以及您试图从中获取的内容,那么可能有一种更快的方法可以在VFP中预处理数据,以便更轻松地批量插入SQL。最后,表中有多少记录被批量插入。数据来自txt文件(这些是由第三方防火墙生成的日志)。数据将存储在sql server上。PK是标识列,因为表中没有自然PK。我已经在这里发布了代码,但是coulumn比我现在尝试插入的要少。目前,我正在尝试用FOPEN()打开文件,用fgets()读取每一行,从而在vfp中执行字符串操作。将此子字符串值存储在表中,然后将表转换为csv或txt文件进行批量插入是一个好主意吗?
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