除了普通的小數據集,你將很難打敗NpgSql的實現copy
的性能,這可以通過你的NpgSqlConnection
對象的BeginTextImport
方法來實現。
因此,無論您的數據如何在應用程序中存在,如果通過文本導入(複製)轉儲輸出,它應該非常快速。這裏是一個如何使用數據表來實現的例子。記住數據表中的列和表中的列將不得不排隊 - 如果沒有,你需要管理這種或那種方式。
這假定NpgSql 3.1.9或更高版本。
object[] outRow = new object[dt.Columns.Count];
using (var writer = conn.BeginTextImport("copy <table> from STDIN WITH NULL AS '' CSV"))
{
foreach (DataRow rw in dt.Rows)
{
for (int col = 0; col < dt.Columns.Count; col++)
outRow[col] = rw[col];
writer.WriteLine(string.Join(",", outRow));
}
}
只要重複...哇,這真的取決於。定義「重複」。如果它只是一個「選擇不同」,那麼它也取決於您期望的重複數量。如果數量很少,那麼List.Exists<>
可能就足夠了,但是如果你有大量的模型,Dictionary對象會使每個查找效率更高。一個典型的列表查找是O(n),而一個字典查找將是O(1)。
這裏有一本字典不同的插入了上面的例子中的一個漂亮的蠻力例如:
object[] outRow = new object[dt.Columns.Count];
Dictionary<string, bool> already = new Dictionary<string, bool>();
bool test;
using (var writer = conn.BeginTextImport("copy <table> from STDIN WITH NULL AS '' CSV"))
{
foreach (DataRow rw in dt.Rows)
{
for (int col = 0; col < dt.Columns.Count; col++)
outRow[col] = rw[col];
string output = string.Join(",", outRow);
if (!already.TryGetValue(output, out test))
{
writer.WriteLine(output);
already.Add(output, true);
}
}
}
免責聲明:這是一個內存豬。如果您可以通過其他方式管理欺騙,或者保證數據的順序,還有其他許多選項。
如果你不能(或不願)使用批量複製插入,東西,這將有助於表現會來包裝你插入到一個事務(NpgSqlTransaction
),但對於行幾十萬,我可以」你明白你爲什麼會這麼做。
感謝您的回答!我認爲,副本是最好的方法。但是,爲什麼使用textcopy?可能使用二進制導入是更好的選擇?哪一個更快? –
是的,二進制是高性能,但它也不是那麼簡單(在我看來)。您可能會驚訝於文本導入的速度。嘗試一下,讓我知道。 – Hambone