¿Hay alguna forma sistemática de obligar a PostgreSQL a cargar una tabla específica en la memoria, o al menos leerla desde el disco para que el sistema la almacene en caché?
¿Hay alguna forma sistemática de obligar a PostgreSQL a cargar una tabla específica en la memoria, o al menos leerla desde el disco para que el sistema la almacene en caché?
Respuestas:
Puede estar interesado en uno de los temas de las listas de correo , es respondido por Tom Lane (desarrollador principal):
[..] Pero mi opinión es que las personas que piensan que son más inteligentes que un algoritmo de almacenamiento en caché LRU suelen estar equivocadas. Si la tabla es muy utilizada, permanecerá en la memoria bien. Si no se usa lo suficiente como para permanecer en la memoria de acuerdo con un algoritmo de LRU, tal vez el espacio de memoria realmente debería gastarse en otra cosa. [..]
También podría estar interesado en una pregunta SO: https://stackoverflow.com/questions/486154/postgresql-temporary-tables y tal vez más apta para https://stackoverflow.com/questions/407006/need-to-load-the -whole-postgresql-database-into-the-ram
Postgres 9.4 finalmente agregó una extensión para precargar los datos de las relaciones en el sistema operativo o la memoria caché del búfer de la base de datos (a su elección):
pg_prewarm
Esto permite alcanzar el rendimiento operativo completo más rápidamente.
Ejecute una vez en su base de datos (instrucciones detalladas aquí ):
CREATE EXTENSION pg_prewarm;
Entonces es simple precargar cualquier relación dada. Ejemplo básico:
SELECT pg_prewarm('my_tbl');
Encuentra la primera tabla nombrada my_tbl
en la ruta de búsqueda y la carga en la memoria caché del búfer de Postgres
O:
SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');
prefetch
emite solicitudes de captación previa asincrónicas al sistema operativo, si esto es compatible, o arroja un error de lo contrario.read
lee el rango de bloques solicitado; a diferenciaprefetch
, esto es sincrónico y compatible con todas las plataformas y compilaciones, pero puede ser más lento.buffer
lee el rango de bloques solicitado en la memoria caché del búfer de la base de datos.
El valor predeterminado es buffer
, que tiene el mayor impacto (mayor costo, mejor efecto).
Lea el manual para más detalles , las citas son de allí.
Depesz también blogueó al respecto.
En el caso general, si tiene suficiente RAM, generalmente puede confiar en el servicio de base de datos para hacer un buen trabajo al mantener las cosas que usa regularmente en la RAM. Algunos sistemas le permiten insinuar que la tabla siempre debe mantenerse en la RAM (lo cual es útil para las tablas más pequeñas que no se usan con frecuencia, pero cuando se usan es importante que respondan lo más rápido posible), pero si pgsql tiene tales sugerencias de tabla debe tener mucho cuidado al usarlos, ya que está reduciendo la cantidad de memoria disponible para almacenar en caché cualquier otra cosa, por lo que podría ralentizar su aplicación en general.
Si está buscando cebar la memoria caché de la página de la base de datos al inicio (por ejemplo, después de un reinicio u otra operación de mantenimiento que hace que la base de datos olvide todo lo que está en caché), escriba un script que haga lo siguiente:
SELECT * FROM <table>
SELECT <primary key fields> FROM <table> ORDER BY <primary key fields>
SELECT <indexed fields> FROM <table> ORDER BY <indexed fields>
(ese último paso se repite para cada índice o curso, y tenga cuidado de tener los campos en la cláusula ORDER BY en el orden correcto)
Después de ejecutar lo anterior, todas las páginas de datos e índices deberían haberse leído y, por lo tanto, estarán en la memoria caché de la página RAM (al menos por el momento). Tenemos scripts como este para nuestras bases de datos de aplicaciones, que se ejecutan después del reinicio para que los primeros usuarios que inicien sesión en el sistema no experimenten una respuesta más lenta. Es mejor escribir a mano cualquier script de este tipo, en lugar de escanear las tablas de definición de base de datos (como sys.objects
/ sys.indexes
/ sys.columns
en MSSQL), luego puede escanear selectivamente los índices que se usan más comúnmente en lugar de escanear todo lo que llevará más tiempo.
SELECT * FROM schema.table
y vi que cargaba toda la tabla de 60GiB en mi caché de búfer PostgreSQL de 100GiB.
Tuve un problema similar:
después de reiniciar el servicio del servidor y todos los datos cobrados cayeron, muchas consultas se llamaron por primera vez donde realmente realmente lento, debido a la complejidad específica de las consultas, hasta que se cobraron todos los índices y datos necesarios. eso significa que, por ejemplo, los usuarios deben presionar una vez cada "elemento" (tiempo de ejecución de 1-3 segundos) y datos relacionados de 50 millones de filas, para que los usuarios ya no experimenten demoras no deseadas. A los usuarios les toma las primeras 3 horas experimentar bloqueos molestos, hasta que se cobra la mayoría de los datos utilizados y los programas están arruinando la mejor calidad con el rendimiento de la producción, finalizan incluso entonces, 2 días, algunos retrasos breves y repentinos, cuando se obtienen menos datos a los que se accede por primera vez ... , para datos estadísticos, etc.
Para resolver esto, escribí una pequeña secuencia de comandos de Python que realiza selecciones en las tablas más pesadas con índices grandes. Tardó 15 minutos en ejecutarse y no hubo retrasos en el rendimiento.
Hmmm, puede ser que el comando COPY ayudaría. Simplemente ejecute COPY a stdout y lea de él. Es posible hacerlo usando pg_dump:
pg_dump -U <user> -t <table> <database> > /dev/null
Otra forma es encontrar todos los archivos de tabla y ejecutarlos cat <files> > /dev/null
.
Aquí está el ejemplo sobre cómo obtener nombres de archivos de tabla:
# SELECT oid, datname FROM pg_database ;
oid | datname
-------+-----------
<...>
16384 | test
-- out of database is 16384
# SELECT oid, relname FROM pg_class WHERE relname like 'fn%';
oid | relname
-------+---------
24576 | fn
(1 row)
-- oid of our table is 24576
entonces, los archivos de la tabla son / ruta / a / pgsql / data / base / 16384/24576 *
Usted también quiere leer índices y tablas de tostados, obtener sus oids de la misma manera.
Por cierto, ¿por qué lo necesitas? Creo que postgresql y OS son lo suficientemente inteligentes como para almacenar en caché los datos más actuales y mantenerlos bien. Eficiencia de caché.
Uso RamDrive de QSoft, que fue comparado como el disco RAM más rápido para Windows. Acabo de usar
initdb -D e:\data
donde e: \ es el lugar del RamDisk.