当前位置: 首页 > 知识库问答 >
问题:

python - psycopg2处理大数据量SQL在execute(sql)卡死?

牧璞
2023-11-08

题目描述

sql='select * from A',A表有8百万数据

前段时间写了数据库互相导数据的Python脚本,是Oracle导入postgreSQL,使用cx_Oracle执行execute(sql)没有任何问题。这次是postgreSQL导入postgreSQL,使用psycopg2执行execute(sql)就直接卡死在这一行了,并且内存占用持续上升。

自己的思路

数据库连接是没有问题的,因为其他少数据量表可以正常执行,A表的SQL写分页也可以正常执行。我也清楚可以通过多次分页实现避免这个bug,但是我想咨询下各位大佬为什么会出现这个问题?按道理来说execute(sql)这里是不会查询数据的,后面应该是通过方法或者循环游标获取数据,但它就是在这里卡住了,持续攀升的内存让我认为它在这里就执行了sql,并且想把这8百万数据加载入内存!这个问题是怎么导致的啊?或者说是psycopg2库的bug???

共有3个答案

蒙墨竹
2023-11-08

用服务器端游标:

with conn.cursor(name='server_cursor') as cursor:    cursor.itersize = 10000  # 设置你要的批量大小    cursor.execute(sql)    for record in cursor:        # 处理记录
范玄裳
2023-11-08

你做了类似这步操作cursor = conn.cursor()还是会出现这个问题?

牟辰龙
2023-11-08

回答

根据你提供的信息,问题可能出在psycopg2库对大数据量的处理上。当你执行一条查询语句,例如 select * from A,psycopg2会试图将所有的数据都加载到内存中,这可能导致内存溢出或程序卡死。

这个问题可能是由于psycopg2的内部机制在处理大量数据时出现了一些问题。对于大数据量的处理,通常需要使用游标(cursor)或者分页查询的方式,以避免一次性加载所有数据到内存中。

你可以尝试以下几种方法来解决这个问题:

  1. 使用游标(cursor):通过游标,你可以逐行获取数据,而不是一次性加载所有数据到内存中。你可以使用 cursor.fetchone()cursor.fetchmany() 方法来获取数据。
  2. 分页查询:通过分页查询,你可以将数据分批次加载到内存中,而不是一次性加载所有数据。例如,你可以使用 LIMITOFFSET 关键字来分页查询。
  3. 批量插入:如果你需要将大量数据插入到数据库中,可以考虑使用批量插入的方式,以减少数据库操作的次数,提高效率。
  4. 检查内存使用:你可以检查程序的内存使用情况,以确定是否出现了内存溢出的问题。如果内存持续上升,可能是由于一次性加载了太多的数据到内存中。

总之,对于大数据量的处理,需要谨慎使用psycopg2库,并采取适当的方法来避免内存溢出或卡死的问题。

 类似资料:
  • 问题内容: 在我的代码中,用户可以上传一个excel文档,希望其中包含电话联系人列表。作为开发人员,我应阅读excel文件,将其转换为dataTable并将其插入数据库。问题是某些客户拥有大量的联系人,例如说5000个和更多的联系人,而当我尝试将这种数据量插入数据库时​​,它崩溃了,并给了我一个超时异常。避免这种异常的最佳方法是什么?它们的任何代码都可以减少insert语句的时间,从而使用户不必等

  • 问题内容: 我有一个Java应用程序,它需要显示大量数据(大约一百万个数据点)。数据并不需要全部同时显示,而仅在用户请求时才显示。该应用程序是桌面应用程序,未与应用程序服务器一起运行或未与任何集中式数据库连接。 我的想法是在计算机上运行数据库并在其中加载数据。在大多数时候,数据库都是只读的,因此我应该能够建立索引以帮助优化查询。如果我在本地系统上运行,则不确定是否应该尝试实现一些缓存(我不确定查询

  • 问题内容: 很简单的问题。 我有一个很大的70gb数据库,其中有五个表中的四个,每个表包含约5000万行。这些表包含大约6年的数据。我们将数据库的空间大小限制为80gb,并且在接下来的6个月左右的时间内我们将迅速接近该空间。 我们只需要在实时数据库中保留大约两年的数据价值。在不使实时数据库(24/7数据库)脱机的情况下,归档较旧数据的最佳方法是什么? 我们正在使用共享存储的主动-被动设置在群集环境

  • 问题内容: Google讨论了有关清理Web访问查询的各种讨论,但我找不到任何解决我所关注的问题的方法: 在ac#程序中清理用户输入数据。这必须通过可逆的转换来完成,而不是通过移除来完成。作为问题的简单示例,我不想破坏爱尔兰的名字。 最好的方法是什么,有没有执行此功能的库函数? 问题答案: 这取决于您所使用的SQL数据库。例如,如果要在MySQL中使用单引号文字,则需要使用反斜杠Dangerous

  • CREATE TABLE充当来自CSVREAD的SELECT*('c://users/h/downloads/SERVES.csv');SQL语句“create TABLE SERVES AS SELECT*FROM CSVREAD([*]'c://users/h/downloads/SERVES.csv')”中的语法错误;SQL语句:CREATE TABLE充当从CSVREAD中选择*('c:/

  • 问题内容: 我想知道是否有人对我即将从事的工作有任何经验。我有几个csv文件,它们的大小都在一个GB左右,我需要将它们加载到oracle数据库中。虽然加载后我的大部分工作都是只读的,但我仍需要不时加载更新。基本上,我只需要一个很好的工具即可一次将多行数据加载到数据库中。 到目前为止,这是我发现的内容: 我可以使用SQL Loader来完成很多工作 我可以使用批量插入命令 某种批量插入。 以某种方式