这属于我继承的项目,不能更改表结构或数据访问模型.我被要求优化用于将数据插入数据库的算法.
我们在表T中有一个数据集.从那里,我们拉出一个我们将调用A的集合.我们还查询XML feed并得到一个我们将调用X的集合.
所有这些更改都需要插回到数据库中.
设置的算法执行以下操作:
Query XML into a LIST
foreach over the XML LIST
look up foreach.item in A via LINQ (i.e. query = from record in A where
record.GUID == foreach.item.GUID
select record)
if query.Count() == 0
insert into A (via context.AddToTableName(newTableNameObject)
else
var currentRecord = query.First()
set all properties on currentRecord = properties from foreach.item
context.SaveChanges()
Run Code Online (Sandbox Code Playgroud)
我知道这不是最理想的.我试图将A放入foreach循环之外的对象(称为queryA),以便将查询移动到内存而不是访问磁盘,但在考虑完之后,我意识到数据库已经在内存中了.
已经将计时器对象添加到算法中,很明显,花费最多时间的是SaveChanges()函数调用.在某些情况下,它是20毫秒,而在其他一些情况下,在可解释的情况下,它会跳到100毫秒.
我宁愿只调用SaveChanges()一次.考虑到我对EF(最好是最薄的)知识的深度以及无法更改表结构并且必须保留不在X中的A的数据的限制,我无法弄清楚如何做到这一点.
建议?
我试图Add()大约18000个对象到我的DBContext.花了大约5分钟.使用SaveChanges()保存此数据的时间更长.我切换到创建一个普通的List并将我的对象添加到它,然后我使用SqlBulkCopy来保存数据.这花了大约5秒钟.
Add方法做了什么,这需要花费这么长时间?
我必须像1M实体一样处理以构建事实.应该有大约相同数量的结果事实(100万).
我遇到的第一个问题是批量插入,实体框架很慢.所以我在实体框架中使用了这种最快的插入方式(来自SLauma的回答).我可以在一分钟内快速插入实体,大约100K.
我遇到的另一个问题是缺乏处理所有内容的内存.所以我已经"分页"了处理过程.为了避免内存不足,如果我从我的100万结果事实中列出一个列表,我会得到.
我的问题是即使使用分页,内存也总是在增长,我不明白为什么.每批后没有释放内存.我认为这很奇怪,因为我在循环的每次迭代中获取重建构建事实并将它们存储到DB中.一旦循环完成,那些应该从内存中释放出来.但它看起来并不是因为每次迭代后都没有释放内存.
在我挖掘更多之前,你能否告诉我你是否看错了什么?更具体地说,为什么在迭代循环之后没有释放内存.
static void Main(string[] args)
{
ReceiptsItemCodeAnalysisContext db = new ReceiptsItemCodeAnalysisContext();
var recon = db.Recons
.Where(r => r.Transacs.Where(t => t.ItemCodeDetails.Count > 0).Count() > 0)
.OrderBy( r => r.ReconNum);
// used for "paging" the processing
var processed = 0;
var total = recon.Count();
var batchSize = 1000; //100000;
var batch = 1;
var skip = 0;
var doBatch = true;
while (doBatch)
{ // list to store facts processed during the batch
List<ReconFact> …Run Code Online (Sandbox Code Playgroud) 我需要使用EF Code First插入大约2500行.
我的原始代码看起来像这样:
foreach(var item in listOfItemsToBeAdded)
{
//biz logic
context.MyStuff.Add(i);
}
Run Code Online (Sandbox Code Playgroud)
这花了很长时间.每次DBSet.Add()通话大约需要2.2秒,相当于大约90分钟.
我重构了这个代码:
var tempItemList = new List<MyStuff>();
foreach(var item in listOfItemsToBeAdded)
{
//biz logic
tempItemList.Add(item)
}
context.MyStuff.ToList().AddRange(tempItemList);
Run Code Online (Sandbox Code Playgroud)
这只需要大约4秒钟才能运行.但是,.ToList()查询当前表中的所有项目,这是非常必要的,从长远来看可能是危险的,甚至更耗时.一个解决方法是做一些事情,context.MyStuff.Where(x=>x.ID = *empty guid*).AddRange(tempItemList)因为我知道永远不会有任何返回.
但我很好奇是否有其他人知道使用EF Code First进行批量插入的有效方法?
我有一个包含数千条记录的数据表。我有一个具有相同数据表字段的 postgres 表。我想每天截断这个表并再次填充数据表的数据。我见过 sql 批量复制,但它在 postgres 上不可用。那么,哪一种是最有效的方法呢?
谢谢。
我有5个实体:
public class Album
{
public int Id { get; set; }
public string Title { get; set; }
public virtual List<AlbumArtist> AlbumArtists { get; set; }
public virtual List<Artist> Artists { get; set; }
public virtual List<Genre> Genres { get; set; }
public virtual List<Song> Songs { get; set; }
}
public class AlbumArtist
{
public int Id { get; set; }
public string Title { get; set; }
public virtual List<Album> Albums { get; set; }
public virtual …Run Code Online (Sandbox Code Playgroud) 我试图通过Entity Framework 6.1.3向MS Sql Server数据库插入大约50.000行,但这需要太长时间.我听了这个回答.在添加每1000个实体后禁用AutoDetectChangesEnabled并调用SaveChanges.它仍然需要大约7-8分钟.我尝试使用远程服务器和本地服务器.没有太大区别.我不认为这是正常的.我忘记了什么吗?
这是我的代码:
static void Main(string[] args)
{
var personCount = 50000;
var personList = new List<Person>();
var random = new Random();
for (int i = 0; i < personCount; i++)
{
personList.Add(new Person
{
CreateDate = DateTime.Now,
DateOfBirth = DateTime.Now,
FirstName = "Name",
IsActive = true,
IsDeleted = false,
LastName = "Surname",
PhoneNumber = "01234567890",
PlaceOfBirth = "Trabzon",
Value0 = random.NextDouble(),
Value1 = random.Next(),
Value10 = random.NextDouble(),
Value2 = random.Next(),
Value3 = random.Next(),
Value4 …Run Code Online (Sandbox Code Playgroud) 我使用PowerShell脚本和.NET Core应用程序将大约50k行插入数据库(App 1(PowerShell)将数据发送到App 2(.NET Core),其中id插入数据).
我正在使用实体框架,我已经在App 2中实现了一个更快插入的机制,这与以下内容类似:实体框架中最快的插入方式
发生的事情是插入需要一段时间,但它完成正常,所有数据正确插入数据库.查询运行大约4分钟.
但是,App 1返回通用的"HTTP错误502.3 - 错误的网关".即使在将所有数据插入数据库之前,也会返回此响应.所以App 2只发回一个错误,但db操作继续,好像什么也没发生.
所以问题是,db插入工作正常,但我无法知道在App 1中,因为我每次都得到的是一般错误.
我尝试在两个应用程序中增加IIS超时,会话超时,读取IIS日志和NET Core生成的应用程序日志.没有成功.
如何使App 2等到查询完成后才能获得正确的响应?
.NET Core版本是1.0.0-preview2-003121
Powershell要求:
$post = Invoke-WebRequest -Uri ([string]$ApiUrl+$moduleApi) -Method Post -ContentType "application/json; charset=utf-8" -Body $json -Headers @{'ClientID' = "$clientID"; "Authorization"="Bearer $encryption"} -ErrorVariable errorMsg -UseBasicParsing -TimeoutSec 600
Run Code Online (Sandbox Code Playgroud) 我有一个大小约为 1.3 GB 的 CSV 文件:
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/4/2021 1:23 PM 1397998768 XBTUSD.csv
Run Code Online (Sandbox Code Playgroud)
这是 Kraken 交易所上比特币交易数据的完整列表。
CSV 中的数据如下所示:
> Get-Content .\XBTUSD.csv | Select-Object -First 10
1381095255,122.00000,0.10000000
1381179030,123.61000,0.10000000
1381201115,123.91000,1.00000000
1381201115,123.90000,0.99160000
1381210004,124.19000,1.00000000
1381210004,124.18000,1.00000000
1381311039,124.01687,1.00000000
1381311093,124.01687,1.00000000
1381311094,123.84000,0.82300000
1381431835,125.85000,1.00000000
Run Code Online (Sandbox Code Playgroud)
有关该文件的更多信息可在此处找到:
该文件可以从这里下载:
https://drive.google.com/drive/folders/1jI3mZvrPbInNAEaIOoMbWvFfgRDZ44TT
请参阅文件XBT.zip。该档案里面是XBTUSD.csv.
如果我在 sqlite 中创建下表:
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/4/2021 1:23 PM 1397998768 XBTUSD.csv
Run Code Online (Sandbox Code Playgroud)
并运行以下命令导入 CSV(以及所需时间):
$a = Get-Date
sqlite3.exe .\kraken-trades.db -cmd '.mode …Run Code Online (Sandbox Code Playgroud) c# ×7
sql-server ×3
database ×2
.net ×1
asp.net ×1
bulkinsert ×1
datatable ×1
postgresql ×1
powershell ×1
sqlbulkcopy ×1