Recommended Free Tools
Para leer una consulta SQL grande en Pandas, combina pd.read_sql_query(..., chunksize=N) con stream_results=True en una conexión SQLAlchemy, si el dialecto y el driver admiten resultados no almacenados en búfer. chunksize entrega filas a Pandas en DataFrames sucesivos, pero por sí solo no garantiza que el driver no haya cargado antes el resultado completo en la memoria del cliente. Ninguna configuración garantiza que 50 millones de filas quepan en cualquier máquina: hay que comprobar el soporte del driver y medir el pico de memoria con datos y transformaciones representativos.
Qué hace realmente chunksize
Al llamar a pd.read_sql_query(sql, conn, chunksize=N), Pandas devuelve un iterador que produce DataFrames de hasta N filas. Puedes procesar cada bloque y continuar con el siguiente, en lugar de convertir toda la consulta en un único DataFrame.
As an Amazon Associate I earn from qualifying purchases.
Eso limita las filas que Pandas convierte en cada DataFrame, pero no necesariamente las que ya están en memoria. Algunos drivers almacenan el conjunto completo de resultados en el cliente antes de entregarlo por partes. En ese caso, los bloques reducen el tamaño de los DataFrames individuales, pero no eliminan por sí solos el pico de memoria causado por el almacenamiento previo del resultado.
Cómo solicitar streaming real con SQLAlchemy
SQLAlchemy distingue entre resultados almacenados en búfer y resultados no almacenados en búfer. Para una consulta grande, la opción stream_results=True solicita el segundo comportamiento cuando el dialecto y el driver lo admiten. La guía de IO de Pandas cita psycopg2 y PyMySQL como ejemplos de drivers con soporte de cursores del lado del servidor; otros drivers pueden comportarse de otra manera.
#1 Best Overall
with engine.connect().execution_options(stream_results=True) as conn:
for chunk in pd.read_sql_query(sql, conn, chunksize=10_000):
procesar_y_persistir(chunk)
del chunk
El tamaño 10_000 es solo un ejemplo para iniciar la evaluación, no una recomendación universal ni un valor validado para una tabla concreta. Ajústalo según la anchura de las filas, sus tipos, el coste de la transformación, la latencia de la consulta y la memoria observada. Confirma también el soporte en la documentación de la combinación concreta de SQLAlchemy, dialecto y driver: configurar la opción no añade compatibilidad donde no existe.
La documentación de Pandas resume la condición técnica así: “Actually streaming the result requires a server-side cursor, which with SQLAlchemy is requested with the stream_results execution option (supported by, e.g., the psycopg2 and pymysql drivers; drivers without server-side cursor support ignore it):” (guía de IO de Pandas).
Rank #2
Qué ocurre según la estrategia de lectura
| Estrategia | Cómo llegan las filas | Qué comprobar |
|---|---|---|
Pandas con chunksize |
Pandas entrega iterativamente DataFrames de hasta el número de filas indicado. | El driver puede haber almacenado el resultado completo en memoria cliente antes de producir el primer bloque; chunksize no lo impide por sí solo. (Pandas) |
Pandas con chunksize y SQLAlchemy con stream_results=True |
Solicita resultados no almacenados en búfer para backends compatibles y permite consumir el resultado por partes. | Verifica el soporte del dialecto y del driver. Los cursores del lado del servidor pueden ahorrar memoria cliente en resultados muy grandes, aunque añaden complejidad y pueden ser menos eficientes con resultados pequeños. (SQLAlchemy 2.1) |
CSV con read_csv(..., chunksize=...) |
Pandas devuelve un TextFileReader para iterar por partes; usecols permite cargar solo las columnas necesarias. |
Esta vía es para archivos CSV: no configura el cursor ni el almacenamiento de resultados de una consulta SQL. (referencia de pandas.read_csv 3.0.6) |
Cómo evitar que el procesamiento por bloques vuelva a consumir toda la memoria
El beneficio del procesamiento incremental depende también de lo que haga el código con cada DataFrame. Si guardas todos los bloques en una lista o los concatenas al final, vuelves a retener —y eventualmente reconstruir— el conjunto completo en memoria.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →- Lee un bloque: consume el siguiente DataFrame del iterador.
- Procésalo: aplica la transformación necesaria a ese bloque, no a una copia acumulada de todos los anteriores.
- Persiste o descarta el resultado: escribe el resultado de forma incremental en el destino adecuado y libera las referencias que ya no necesites.
- Continúa: solo entonces avanza al siguiente bloque, si el flujo de trabajo permite hacerlo así.
Esta pauta ayuda a mantener acotados los datos retenidos por el código de aplicación; no es una garantía de rendimiento. La memoria también depende del driver, del ancho y los tipos de las columnas, de las copias intermedias y de la transformación.
Cómo elegir el tamaño de bloque y verificar el resultado
No hay un tamaño de bloque establecido para una tabla desconocida. Empieza con un valor moderado y mide el pico de memoria en el mismo entorno donde se ejecutará el proceso, usando datos representativos y la transformación real. Ajusta el tamaño de acuerdo con esa medición y con el tiempo que tarda cada bloque.
- Comprueba las versiones instaladas de Pandas, SQLAlchemy y el driver y consulta la documentación de esa combinación.
- Verifica explícitamente si el dialecto y el driver admiten cursores del lado del servidor o resultados no almacenados en búfer.
- Observa el uso máximo de memoria, no solo el tamaño de cada DataFrame.
- Evalúa si el procesamiento puede persistir cada resultado sin acumular los bloques anteriores.
Las fuentes técnicas citadas no publican una cifra de tiempo, memoria o éxito para procesar exactamente 50 millones de filas, ni establecen un tamaño de bloque adecuado para una tabla concreta. Por eso, los 50 millones son el tamaño del problema planteado, no una promesa de que este patrón evitará un OOM en cualquier combinación de datos, código y máquina.
Rank #4
Si los datos están en un CSV, no en una consulta SQL
Para un archivo CSV, pd.read_csv(..., chunksize=N) devuelve un TextFileReader que puedes recorrer por partes. Si solo necesitas algunas columnas, usecols puede evitar cargar las demás. Esto ayuda a tratar archivos grandes, pero no es equivalente a stream_results=True: esa opción se refiere a cómo se obtienen los resultados de una consulta SQL a través de SQLAlchemy.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteQuick Recap
Best Value
Fuentes y documentación
- Pandas: guía de IO, consultas SQL y
chunksize. - SQLAlchemy 2.1: cursores del lado del servidor y conexiones.
- Pandas 3.0.6: referencia de
pandas.read_csv.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




