我有一长串ID填充的员工列表。我想并行添加数据库以加快处理速度。 vb.net中使用parallel.foreach在列表中的每个项目上调用函数的正确语法是什么。以下是这样做的连续方式。
Dim employees As New List(Of Employee)()
For Each element As String In ids
Dim emp As New Employee(element)
employees.Add(emp)
Next
For Each emp In employees
emp.AddToDatabase()
Next
答案 0 :(得分:4)
语法为:
Parallel.ForEach(employees, Sub(emp) emp.AddToDatabase())
但是,并行执行数据库插入实际上会更快,这是值得怀疑的。唯一可能的加速是在实际插入之前的开销,最后数据库一次只能对表执行一次插入。
您可以尝试加速插入的一件事是在一个查询中放入几个插入,即将员工分成小批量。
答案 1 :(得分:0)
这看起来像XY problem,你已经决定了解决方案。
我建议你最好退一步,找出如何在一个查询中添加所有数据,而不是尽可能快地解决大量查询。通常,一个查询将比许多查询更快。
您在评论中指出“这是一个未来更复杂问题的简单示例”,因此我将举例说明将数据添加到只包含文件名和关键字的列的表中,期望您可以扩展它以供将来使用。
首先,表的定义:
CREATE TABLE [dbo].[Keywords](
[Filename] [nvarchar](256) NOT NULL,
[Keyword] [nvarchar](64) NOT NULL
) ON [PRIMARY]
然后是数据库中用户定义的表类型:
CREATE TYPE [dbo].[filename_keyword_tbltype] AS TABLE(
[Filename] [nvarchar](256) NOT NULL,
[Keyword] [nvarchar](64) NOT NULL,
PRIMARY KEY CLUSTERED -- may not apply to you
(
[Keyword] ASC -- may not apply to you
)WITH (IGNORE_DUP_KEY = OFF) -- may not apply to you
)
必须在用户定义的表类型上设置权限:
GRANT EXECUTE ON TYPE::[filename_tbltype] TO [APPROPRIATE\USER_GOES_HERE]
现在数据库已设置为创建存储过程来处理将发送给它的数据:
CREATE PROCEDURE [dbo].[AddKeywords]
@Data [dbo].[filename_keyword_tbltype] ReadOnly
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO Keywords
SELECT [Filename],[Keyword]
FROM @Data;
END
最后可以编写代码以一次性发送所有数据:
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
' ...
sqlcmd = New SqlCommand("AddKeywords", sqlConn)
sqlcmd.CommandType = CommandType.StoredProcedure
Dim tvpData As New List(Of SqlDataRecord)
Dim tvpDataType(1) As SqlMetaData
tvpDataType(0) = New SqlMetaData("Filename", SqlDbType.NVarChar, 256)
tvpDataType(1) = New SqlMetaData("Keyword", SqlDbType.NVarChar, 64)
' metadata.Keywords is a List(Of String) with the keywords for a file
For Each kwd In metadata.Keywords
Dim rec = New SqlDataRecord(tvpDataType)
' smallName is simply the filename
rec.SetSqlString(0, smallName)
rec.SetSqlString(1, kwd.ToLower(CultureInfo.InvariantCulture))
tvpData.Add(rec)
Next
sqlParam = New SqlParameter("@Data", SqlDbType.Structured)
sqlParam.TypeName = "filename_keyword_tbltype"
sqlParam.Value = tvpData
sqlcmd.Parameters.Add(sqlParam)
sqlConn.Open()
sqlcmd.ExecuteNonQuery()
sqlConn.Close()
请注意,所有数据都是一次性发送的,无论是一条记录还是一千条。
参考:Arrays and Lists in SQL Server 2008 - Using Table-Valued Parameters