乍一看这似乎很奇怪,但我希望这是有道理的! 我有一list<string>
mysql插入语句,我逐个迭代和执行,这工作正常,但我试图实现的是性能提升。
例如,我想在单个查询中传递所有值,而不是
INSERT INTO tb1(field1,field2,field3) VALUES (1,2,3);
INSERT INTO tb1(field1,field2,field3) VALUES (4,5,6);
INSERT INTO tb1(field1,field2,field3) VALUES (7,8,9);
我想做
INSERT INTO tb1(field1,field2,field3) VALUES (1,2,3), (4,5,6), (7,8,9);
所以基本上我需要构建一个长查询字符串,将第一个查询作为起点,并将括号部分从值附加到末尾,无论列表中的对象计数是多少 - 这可能吗?
这应该有效。我正在使用regex
来查找列和值,并使用string.Substring
来查找表名。然后,我将所有这些与string.Format
和string.Join
以及一个简单的Linq查询放在一起:
IEnumerable<string> inserts = // add your insert-strings here;
string firstInsert = inserts.First();
int tableIndex = firstInsert.IndexOf("INSERT INTO ") + "INSERT INTO ".Length;
string table = firstInsert.Substring(
tableIndex, firstInsert.IndexOf("(", tableIndex) - tableIndex);
var regex = new System.Text.RegularExpressions.Regex(@"(([^)]+))",System.Text.RegularExpressions.RegexOptions.Compiled);
string columns = regex.Matches(firstInsert)[0].Value;
IEnumerable<string> values = inserts.Select(sql => regex.Matches(sql)[1].Value);
string insertAll = string.Format("INSERT INTO {0}{1} VALUES {2};"
, table
, columns
, string.Join(",", values));
演示您的示例数据。
以防万一您可能要插入到不同的表(或表中的列集),
var perTableQueries = separateQueries
.Select(s => s.Split(new[] {" VALUES "}, StringSplitOptions.None))
.Where(a => a.Length == 2)
.GroupBy(a => a[0], StringComparer.InvariantCultureIgnoreCase)
.Select(g => String.Format("{0} VALUES {1};",
g.Key,
String.Join(",", g.Select(a => a[1].TrimEnd(';')).ToArray())));
将为每个表/列集进行一次插入(如果您的 SQL 是一致的)。
也就是说,如果您为每一行向数据库发出单独的请求,则最大的性能节省可能只是
var singleRequest = String.Join("", perTableQueries.ToArray());