web-dev-qa-db-fra.com

Différence de performances entre MySQL et PostgreSQL pour le même schéma / requêtes

Je suis un DBA débutant et j'ai de l'expérience dans Microsoft SQL Server mais je veux passer à FLOSS.

Je démarre une entreprise et nous développons une application (PHP) avec un backend Postgres, et nous avons également fait des tests en comparant avec MySQL. Nous observons que MySQL est deux fois plus rapide que PostgreSQL.

J'ai fait un test de performance tangible:

  • Mêmes colonnes dans le tableau avec des types de données de colonne équivalents.
  • Même nombre de lignes.
  • Mêmes index dans les deux (clé primaire incluse).
  • La charge CPU est inactive et la machine Postgres c'est nettement mieux.
  • Et la même requête (évidemment).

Qu'est-ce que je fais mal?

P.S: J'ai lu de nombreux "howtos" sur le réglage des performances des moteurs de base de données.
P.S (2): Nous utilisons InnoDB (un fichier par table) sur la base de données MySQL.


Salut Mat!

J'ai fait les trois requêtes de sélection les plus courantes (et les plus difficiles).

La question du disque n'est certainement pas la même; À Postgres, c'est un SSD (presque trois fois plus rapide).

Données de cache 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                    |
+------------------------------+----------------------+

Je ne sais pas comment afficher cela dans PostgreSQL.

Merci d'avance.

20
Javier Valencia

MySQL et PostgreSQL sont très différents en termes de performances. Les tables InnoDB et PostgreSQL sont optimisées pour différents types de requêtes. Comprendre ces différences est important pour comprendre comment obtenir de bonnes performances de l'un ou l'autre.

À titre d'exemple, regardons la différence la plus évidente.

PostgreSQL vs MySQL/InnoDB Table Structure et ce que cela signifie pour les performances

En général, sur des charges de travail complexes, PostgreSQL sera plus rapide, mais sur les recherches de clé primaire simples, MySQL avec InnoDB sera plus rapide.

Les tables PostgreSQL sont des tables de tas. Il n'y a pas d'option pour construire une table qui n'est pas une table de tas. La commande cluster réécrit simplement le tas ordonné par un index spécifié. Les index fournissent ensuite des emplacements de segment pour les tuples avec différentes valeurs. Les index ne peuvent pas être parcourus dans l'ordre physique, uniquement dans l'ordre logique, de sorte qu'ils ont beaucoup d'E/S de disque aléatoires tandis que la lecture séquentielle d'une table signifie généralement beaucoup d'E/S de disque séquentielles, car vous pouvez lire une table dans l'ordre physique. Les E/S de disque séquentielles peuvent utiliser le cache de lecture anticipée et certaines autres optimisations au niveau du système d'exploitation.

Cela signifie que si vous avez besoin d'une partie importante des enregistrements ou de plusieurs pages, il est généralement plus rapide de simplement lire les pages du disque. D'un autre côté, une recherche de clé primaire pour une table nécessite de frapper l'index, de rechercher l'emplacement dans le fichier, puis de frapper la table de tas et d'extraire l'enregistrement. Cela signifie un certain nombre d'E/S de disque aléatoires.

InnoDB utilise une approche différente. Avec InnoDB, la table est un index b-tree avec les données réelles dans la charge utile de l'index. Cela signifie qu'une recherche de clé primaire peut déjà extraire les données de la page feuille, et donc moins d'E/S de disque aléatoires sont nécessaires pour cela. Dans le même temps, une analyse d'index nécessite de parcourir deux index au lieu d'un, ce qui signifie que l'utilisation de tout index autre que la clé primaire finit par être plus lente et les analyses séquentielles sont plus lentes encore.

Obtenir des diagnostics dans PostgreSQL

Je pense que vous voulez utiliser quelque chose comme:

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

Cela vous donnera le plan de requête, les estimations initiales, les temps réels, l'utilisation du tampon et bien plus encore.

43
Chris Travers