Diferencia de rendimiento entre MySQL y PostgreSQL para el mismo esquema / consultas [cerrado]

20

Soy un DBA novato y tengo experiencia en Microsoft SQL Server pero quiero saltar a FLOSS.

Estoy comenzando una empresa, y desarrollamos una aplicación (PHP) con un backend de Postgres, e hicimos algunas pruebas en comparación con MySQL también. Observamos que MySQL es dos veces más rápido que PostgreSQL.

Hice una prueba de rendimiento tangible:

  • Las mismas columnas en la tabla con tipos de datos de columna equivalentes.
  • El mismo número de filas.
  • Los mismos índices en ambos (clave primaria incluida).
  • La carga de la CPU está inactiva y la máquina Postgres es significativamente mejor.
  • Y la misma consulta (obviamente).

¿Qué estoy haciendo mal?

PD: leí muchos "howtos" sobre ajuste de rendimiento para motores de bases de datos.
PS (2): Estamos usando InnoDB (un archivo por tabla) en la base de datos MySQL.


Hola mat

Hice las tres consultas de selección comunes (y más difíciles).

La pregunta sobre el disco, ciertamente no es lo mismo; En Postgres es un SSD (casi tres veces más rápido).

Datos de caché de MySQL:

+------------------------------+----------------------+
| Variable_name                | Value                |
+------------------------------+----------------------+
| binlog_cache_size            | 32768                |
| have_query_cache             | YES                  |
| key_cache_age_threshold      | 300                  |
| key_cache_block_size         | 1024                 |
| key_cache_division_limit     | 100                  |
| max_binlog_cache_size        | 18446744073709547520 |
| query_cache_limit            | 1048576              |
| query_cache_min_res_unit     | 4096                 |
| query_cache_size             | 16777216             |
| query_cache_type             | ON                   |
| query_cache_wlock_invalidate | OFF                  |
| table_definition_cache       | 256                  |
| table_open_cache             | 64                   |
| thread_cache_size            | 8                    |
+------------------------------+----------------------+

No sé cómo ver esto en PostgreSQL.

Gracias por adelantado.

Javier Valencia
fuente
Perdón por mi inglés
Javier Valencia
(Su inglés está bien.) ¿Hizo pruebas de carga o solo consultas individuales? ¿Podría mostrar la configuración de la base de datos que utilizó (especialmente cosas como el tamaño de la memoria caché)? (¿Los mismos discos en ambos casos, supongo?)
Mat
1
¿Puede publicar la consulta y el plan de ejecución de Postgres usando explain analyze. Para que sea más fácil de leer, puede cargar el plan para explicar.depesz.com
a_horse_with_no_name
1
Si Postgres se está ejecutando en un SSD, seguramente tendrá que sintonizarpostgresql.conf
a_horse_with_no_name el
1
@JavierValencia: si pudo solucionar el problema, agregue una respuesta que describa lo que hizo para que otros puedan aprender de eso. También puede aceptar su propia respuesta para marcar esta pregunta como resuelta
a_horse_with_no_name

Respuestas:

41

MySQL y PostgreSQL son bastante diferentes en cuanto al rendimiento. Las tablas InnoDB y PostgreSQL están optimizadas para diferentes tipos de consultas. Comprender estas diferencias es importante para comprender cómo obtener un buen rendimiento de cualquiera de ellas.

Como ejemplo, veamos la diferencia más obvia.

PostgreSQL vs MySQL / InnoDB Estructura de tabla y lo que esto significa para el rendimiento

En general, en cargas de trabajo complejas, PostgreSQL será más rápido, pero en búsquedas simples de clave primaria MySQL con InnoDB será más rápido.

Las tablas PostgreSQL son tablas de montón. No hay opción para construir una tabla que no sea una tabla de montón. El clustercomando simplemente reescribe el montón ordenado por un índice específico. Los índices proporcionan ubicaciones de almacenamiento dinámico para tuplas con varios valores. Los índices no se pueden recorrer en orden físico, solo en orden lógico, por lo que tienen muchas E / S de disco aleatorias mientras que leer una tabla secuencialmente generalmente significa muchas E / S de disco secuenciales, ya que puede leer una tabla en orden físico. La E / S de disco secuencial puede usar caché de lectura anticipada y alguna otra optimización de nivel de sistema operativo.

Lo que esto significa es que si necesita una parte importante de los registros o en unas pocas páginas, generalmente es más rápido leer las páginas desde el disco. Por otro lado, una búsqueda de clave primaria para una tabla requiere presionar el índice, buscar la ubicación en el archivo, luego presionar la tabla de montón y extraer el registro. Esto significa una cantidad de piezas de E / S de disco aleatorias.

InnoDB usa un enfoque diferente. Con InnoDB, la tabla es un índice b-tree con los datos reales en la carga útil del índice. Esto significa que una búsqueda de clave principal ya puede extraer los datos de la página principal, por lo que se requiere menos E / S de disco al azar para esto. Al mismo tiempo, un escaneo de índice requiere atravesar dos índices en lugar de uno, lo que significa que el uso de cualquier índice que no sea la clave principal termina siendo más lento y los escaneos secuenciales son aún más lentos.

Obteniendo diagnósticos en PostgreSQL

Creo que quieres usar algo como:

 EXPLAIN (analyse, buffers, verbose)
 [query];

Eso le dará el plan de consulta, estimaciones iniciales, tiempos reales, uso del búfer y mucho más.

Chris Travers
fuente
44
+1 para EXPLICAR (analizar, buffers, detallado)
karmakaze
@ChrisTravers gracias por una gran respuesta! Usted dijo: "... los análisis secuenciales (de InnoDB) son más lentos". ¿Podría explicar qué quiere decir con exploraciones secuenciales en este contexto?
VB_
Gracias. Modificaré la respuesta Los escaneos "secuenciales" en InnoDB están en orden de índice lógico, por lo que tiene más E / S aleatorias y ninguna ayuda de almacenamiento en caché de lectura anticipada.
Chris Travers
Gracias por una buena respuesta. Para cualquier persona curiosa acerca de los internos de postgres, recomiendo esta publicación: interdb.jp/pg/pgsql01.html Explique cómo Postgres almacena los datos como tabla de almacenamiento dinámico.
hqt