微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PostgreSQL-IN子句优化超过3000个值

如何解决PostgreSQL-IN子句优化超过3000个值

我有一个应用程序,用户将上载具有10,000行以上的excel文件(.xlsx或.csv),其中单列“ partId”包含要在数据库中查找的值

我将读取excel值并将其存储在list对象中,并将该列表作为参数传递给内部构建IN子句查询的Spring Boot JPA存储库find方法

                // Read excel file
                stream = new   ByteArrayInputStream(file.getBytes());
                wb = WorkbookFactory.create(stream);
                org.apache.poi.ss.usermodel.Sheet sheet = wb.getSheetAt(wb.getActiveSheetIndex());
                
                Iterator<Row> rowIterator = sheet.rowIterator();
                
                while(rowIterator.hasNext()) {
                    Row row = rowIterator.next();
                    Cell cell = row.getCell(0);
                    System.out.println(cell.getStringCellValue());
                    vinList.add(cell.getStringCellValue());
                }
                
                //JPA repository method that I used
                  findByPartIdInAndSecondaryId(List<String> partIds);

我阅读了许多文章,在上述情况下,我也遇到了同样的情况,即使用IN查询无法处理大量数据。

如何优化上述方案或编写新的优化查询

此外,请让我知道,除了上述代码片段之外,是否还有优化的读取excel文件的方式

那会很有帮助!!预先感谢!

解决方法

如果列表确实很大,您将永远不会快如闪电。

我看到几个选项:

  1. 发送一个带有大型IN列表的查询,就像您在问题中提到的那样。

  2. 构造一个带有大VALUES子句的联接语句:

    SELECT ... FROM mytable
       JOIN (VALUES (42),(101),(43),...) AS tmp(col)
          ON mytable.id = tmp.col;
    
  3. 使用这些值创建一个临时表并与之连接:

    BEGIN;
    CREATE TEMP TABLE tmp(col bigint) ON COMMIT DROP;
    

    然后选择

    COPY tmp FROM STDIN; -- if Spring supports COPY
    

    INSERT INTO tmp VALUES (42),...; -- if not
    

    然后

    ANALYZE tmp;  -- for good statistics
    SELECT ... FROM mytable
       JOIN tmp ON mytable.id = tmp.col;
    COMMIT;  -- drops the temporary table
    

其中最快的最好由您的案例的反复试验确定;我认为不能说其中一种方法总是会击败其他方法。

一些注意事项:

  • 解决方案1.和2.可能会产生非常大的语句,而解决方案3.可能会分成较小的块。

  • 解决方案3.除非列表很大,否则很有可能会变慢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。