【问题标题】:Optimize postgress query for large set of data为大量数据优化 postgres 查询
【发布时间】:2020-03-03 08:51:01
【问题描述】:

存在一个包含大约 400 万行产品信息的 Postgress 数据库表。可用的列有产品id、SKU、产品条形码(array field)和产品描述等。在这里,用户将上传CSV产品数据文件。每个产品可能包含多个条形码。数据将根据数据库中现有的产品条形码进行更新。如果条形码已经存在,则将跳过来自CSV 文件的产品行,或者不会添加来自CSV 的产品。否则,将添加一个包含产品信息的新行,并创建一个任务以手动验证插入的产品。这些验证过程由管理员手动完成。所以我必须在向表中插入数据之前检查每一行,并且查询时间非常高,因为有大量数据。条形码列已编入索引。

我用来检查条形码是否存在的查询:

SELECT * FROM retail_retailinventory WHERE ARRAY['*****'] <@ barcodes

但是,如果未找到任何匹配项,我必须触发 5 次插入到不同模型(如 Inventory、PosModel 和 Task 模型)中。都是依赖的。所以这个操作必须同步触发。我尝试使用bulk_create,但由于我必须维护模型之间的外键关系,因此无法成功。此插入过程正在填满大部分内存并发生超时。

有没有办法优化流程?或者在这种情况下应用机器学习的任何范围?我担心的是,如果我应用 ML,每次将新行插入数据库时​​都需要训练机器,这不是一个好的解决方案。

任何建议将不胜感激。

谢谢。

【问题讨论】:

    标签: django python-3.x postgresql django-models


    【解决方案1】:

    如果运行它的进程的内存没有问题,您可以执行以下操作:

    from itertools import chain
    existing_barcodes = set(chain.from_iterable(RetailInventory.objects.all().values_list('barcodes', flat=True)))
    
    while csv_processing:
        line = # next csv line
        if line['barcode'] in existing_barcodes:
            continue
    

    理想情况下,您可以将初始提取限制为仅相关产品。所以也许迭代 CSV 两次?第一个获取产品和条形码,以便您在单个查询中查看哪些实际上是新的,然后第二个处理它们。

    【讨论】:

      【解决方案2】:

      您可以创建索引:

      create index on retail_retailinventory using GIN (barcodes)
      

      然后将WHERE子句改写为:

      WHERE ARRAY['*****'] <@ barcodes
      

      【讨论】:

      • 谢谢@jjanes。我索引了该列并获得了一些性能。但是,我遇到了另一个问题。我编辑了这个问题。有时间就看看吧。感谢您的回答。
      猜你喜欢
      • 2017-12-25
      • 2022-01-24
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多