背景
通常,您希望将数据从CSV文件加载到数据库中。 通常,这根本不是问题,但是在某些情况下会出现性能问题,尤其是当您要加载大量数据时。 在这种情况下,“大量”是指CSV文件,具有500MB至1GB的数据和数百万行。
在本文中,我将重点讨论无法使用数据库实用程序加载CSV文件的情况(例如PostgreSQL COPY),因为您需要在此过程中进行转换。
同样,在这里值得注意的是,这种大小的数据负载应始终受到质疑,您应该尝试找到更合适的方法来进行处理。 始终检查是否可以使用COPY之类的数据库引擎实用程序将数据直接复制到数据库中。 与使用ORM和应用程序代码相比,这些类型的操作几乎总是具有更高的性能。
假设我们有两个模型:Product和ProductCategory。我们从不同的组织部门获取数据,并且必须将数据加载到系统中。我们的Django模型如下所示:
数据结构非常简单,但是足以显示海量数据负载带来的问题。 这里需要注意的一件事是Product和ProductCategory之间的关系。 在这种情况下,我们可以预期产品类别的数量将比产品数量低几个数量级。
我们还需要一个用于CSV文件的生成器。 CSV文件包含以下列:
product_name
product_code
price
product_category_name
product_category_code
使用上面的脚本,您可以创建一个CSV文件,其中包含我们进行负载测试所需的数据。您可以在调用参数时传递数字,这将是生成的文件中的行数:
上面的命令将创建一个包含10,000个产品的文件。请注意,脚本现在正在跳过CSV标头。
这里要小心,因为1000万行将创建一个大小约为600MB的文件。
现在,我们只需要一个简单的Django管理命令即可加载文件。 我们不会通过视图执行此操作,因为我们已经知道文件很大。 这意味着我们将需要使用请求处理程序上载约500MB的文件,结果是将文件加载到内存中。 这是低效的。
现在,该命令具有简单的数据加载实现,还显示了处理CSV文件所需的时间:
对于200种产品,以上代码在0.220191秒内执行。对于100,000种产品,它花费了103.066553秒。一百万种产品可能要花十倍的时间。我们如何优化使其更快?
优化 【不要将整个文件加载到内存中、迭代时不要进行不必要的查询、不要每次保存一个元素】
详情参阅 - 亚图跨际