场景:我想为地址编写自己的Autocomplete,就像谷歌提供的那样。(非常基本的:街道,豪森数,城市,邮政编码,乡村)。它仅供私人使用和培训之用。首先,我想覆盖大约100万个地址。
使用的技术: .Net Framework (非核心)、C#、Visual、OSMSharp、Microsoft、Web 2(尽管我将来可能会切换到ASP.Net Core)。
方法:
Demo-Purposes)
)
问题:第4步走的太长了。对于osm.pbf格式的"Regierungsbezirk ln“这样的文件,大约为160 GB(未压缩的osm文件大约为2.8GB),其中讨论了4到5个小时。我想优化这个。另一方面,将DataTable大容量复制到数据库(大约100万行)只需要大约5秒。(哇哦。令人惊叹)
最小复制: https://github.com/Cr3pit0/OSM2Database-Minimal-Reproduction
我尝试了什么:
代码摘录:
public static DataTable getDataTable_fromOSMFile(string FileDownloadPath)
{
Console.WriteLine("Finished Downloading. Reading File into Stream...");
using (var fileStream = new FileInfo(FileDownloadPath).OpenRead())
{
PBFOsmStreamSource source = new PBFOsmStreamSource(fileStream);
if (source.Any() == false)
{
return new DataTable();
}
Console.WriteLine("Finished Reading File into Stream. Filtering and Formatting RawData to Addresses...");
Console.WriteLine();
DataTable dataTable = convertAdressList_toDataTable(
source.Where(x => x.Type == OsmGeoType.Way && x.Tags.Count > 0 && x.Tags.ContainsKey("addr:street"))
.Select(Address.fromOSMGeo)
.Distinct(new AddressComparer())
);
return dataTable;
}
};private static DataTable convertAdressList_toDataTable(IEnumerable<Address> addresses)
{
DataTable dataTable = new DataTable();
if (addresses.Any() == false)
{
return dataTable;
}
dataTable.Columns.Add("Id");
dataTable.Columns.Add("Street");
dataTable.Columns.Add("Housenumber");
dataTable.Columns.Add("City");
dataTable.Columns.Add("Postcode");
dataTable.Columns.Add("Country");
Int32 counter = 0;
Console.WriteLine("Finished Filtering and Formatting. Writing Addresses From Stream to a DataTable Class for the Database-SQLBulkCopy-Process ");
foreach (Address address in addresses)
{
dataTable.Rows.Add(counter + 1, address.Street, address.Housenumber, address.City, address.Postcode, address.Country);
counter++;
if (counter % 10000 == 0 && counter != 0)
{
Console.WriteLine("Wrote " + counter + " Rows From Stream to DataTable.");
}
}
return dataTable;
};发布于 2020-01-14 16:23:08
好的,我想我明白了。对于文件大小约为600 of的文件和过滤后的310万行数据,Im只需12分钟。
我尝试的第一件事是用FastMember替换填充我的FastMember的逻辑。这是可行的,但并没有实现我所期望的业绩提升(我在3个小时后取消了这个过程.)。经过更多的研究后,我偶然发现了一个名为"osm2mssql“(https://archive.codeplex.com/?p=osm2mssql)的老项目。我使用了代码的一小部分,它直接从osm.pbf文件中读取数据,并将其修改为我的用例(→,用于从方式中提取地址数据)。我确实使用FastMember为Datatable编写了一个IEnumerable<Address>,但是我不需要OSM和它们所拥有的任何额外的依赖项。非常感谢FastMember的建议。我一定会在今后的项目中牢记这一图书馆。
对于那些感兴趣的人,我相应地更新了我的Github (https://github.com/Cr3pit0/OSM2Database-Minimal-Reproduction) (尽管我没有彻底测试它,因为我从test转到了真正的交易,这是一个Web )。
我很确定它可以被进一步优化,但我认为我现在并不在乎。我想,对于一个每月可能会调用一次来更新整个数据库的方法来说,12分钟是可以的。现在,我可以继续操作对Autocomplete的查询。
所以非常感谢谁写了"osm2mssql“。
https://stackoverflow.com/questions/59680569
复制相似问题