Próbuję dowiedzieć się, w jaki sposób mogę poprawić wydajność wstawiania w tabeli tymczasowej w programie SQL Server przy użyciu C#. Niektórzy twierdzą, że powinienem użyć SQLBulkCopy, ale muszę zrobić coś złego, ponieważ wydaje się, że działa znacznie wolniej niż po prostu tworzenie łańcucha wstawiania SQL.Najszybszy sposób wstawienia 30 tysięcy wierszy w tabeli tymczasowej na serwerze SQL z C#
Mój kod, aby utworzyć tabelę przy użyciu SQLBulkCopy jest poniżej:
public void MakeTable(string tableName, List<string> ids, SqlConnection connection)
{
SqlCommand cmd = new SqlCommand("CREATE TABLE ##" + tableName + " (ID int)", connection);
cmd.ExecuteNonQuery();
DataTable localTempTable = new DataTable(tableName);
DataColumn id = new DataColumn();
id.DataType = System.Type.GetType("System.Int32");
id.ColumnName = "ID";
localTempTable.Columns.Add(id);
foreach (var item in ids)
{
DataRow row = localTempTable.NewRow();
row[0] = item;
localTempTable.Rows.Add(row);
localTempTable.AcceptChanges();
}
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
bulkCopy.DestinationTableName = "##" + tableName;
bulkCopy.WriteToServer(localTempTable);
}
}
W ten sposób moje wstawki zabrać dużo czasu, aby uruchomić. Mam moje wkładki do szybszej pracy w inny sposób:
stworzyłem trochę wkładki jako ciąg i dołączył go w moim SQL utworzyć temp oświadczenie tabeli:
Utworzenie wkładkami ciąg:
public string prepareInserts(string tableName, List<string> ids)
{
List<string> inserts = new List<string>();
var total = ids.Select(p => p).Count();
var size = 1000;
var insert = 1;
var skip = size * (insert - 1);
var canPage = skip < total;
while (canPage)
{
inserts.Add(" insert into ##" + tableName + @" (ID) values " + String.Join(",", ids.Select(p => string.Format("({0})", p))
.Skip(skip)
.Take(size)
.ToArray()));
insert++;
skip = size * (insert - 1);
canPage = skip < total;
}
string joinedInserts = String.Join("\r\n", inserts.ToArray());
return joinedInserts;
}
Korzystanie z nich w SQL po utworzeniu zapytania:
inserts = prepareInserts(tableName, ids);
var query = @"IF EXISTS
(
SELECT *
FROM tempdb.dbo.sysobjects
WHERE ID = OBJECT_ID(N'tempdb..##" + tableName + @"')
)
BEGIN
DELETE FROM ##" + tableName + @"
END
ELSE
BEGIN
CREATE TABLE ##" + tableName + @"
(ID int)
END " + inserts;
var command = new SqlCommand(query, sqlConnection);
...
Ponieważ widziałem ludzie mówią mi (na wymianie stosu https://dba.stackexchange.com/questions/44217/fastest-way-to-insert-30-thousand-rows-in-sql-server/44222?noredirect=1#comment78137_44222), który należy użyć S QLBulkCopy i że byłoby to szybsze, uważam, że powinienem poprawić sposób, w jaki to robię. Więc jeśli ktoś może zasugerować, w jaki sposób mogę poprawić mój kod SQLBulkCopy LUB powiedzieć, czy istnieje lepsza instrukcja wstawiania, która może poprawić wydajność mojej aplikacji, która byłaby świetna.
Skąd dane na tej liście łańcuchów pochodzą w pierwszej kolejności? –
To będzie zestaw kluczy, które będą pochodzić z innej aplikacji. Jeszcze nie zrobiłem tego linku.Na razie jest to tablica, którą utworzyłem z pewnymi identyfikatorami do testu. – Jenninha
30 000 identyfikatorów prawdopodobnie pochodzi z bazy danych. Jeśli tak, chciałbym znaleźć sposób na to wszystko z sql. –