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


20

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 est nettement meilleure.
  • Et la même requête (évidemment).

Qu'est-ce que je fais mal?

PS: J'ai lu de nombreux "howtos" sur le réglage des performances des moteurs de base de données.
PS (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.


Désolé pour mon anglais
Javier Valencia

(Votre anglais est parfait.) Avez-vous effectué des tests de chargement ou simplement des requêtes individuelles? Pourriez-vous montrer les paramètres de base de données que vous avez utilisés (en particulier des choses comme la taille du cache)? (Même disques dans les deux cas, je suppose?)
Mat

1
Pouvez-vous publier la requête et le plan d'exécution Postgres en utilisant explain analyze. Pour faciliter la lecture, vous pouvez télécharger le plan de explain.depesz.com
a_horse_with_no_name

1
Si Postgres fonctionne sur un SSD, vous devez presque certainement réglerpostgresql.conf
a_horse_with_no_name

1
@JavierValencia: si vous avez pu résoudre le problème, veuillez ajouter une réponse décrivant ce que vous avez fait pour que les autres puissent en tirer des leçons. Vous pouvez également accepter votre propre réponse afin de marquer cette question comme résolue
a_horse_with_no_name

Réponses:


41

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 clustercommande 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 toucher 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 de la mémoire tampon et bien plus encore.


4
+1 pour EXPLAIN (analyse, tampons, verbeux)
karmakaze

@ChrisTravers merci pour une excellente réponse! Vous avez dit: "... (InnoDB) les analyses séquentielles sont plus lentes". Pourriez-vous expliquer ce que vous entendez par analyses séquentielles dans ce contexte?
VB_

Merci. Je modifierai la réponse. Les analyses "séquentielles" dans InnoDB sont dans un ordre logique d'index, vous avez donc plus d'E / S aléatoires et aucune aide de la mise en cache à lecture anticipée.
Chris Travers du

Merci pour la bonne réponse. Pour tous ceux qui sont curieux de connaître l'interne de postgres, je recommande ce post: interdb.jp/pg/pgsql01.html Expliquez comment Postgres stocke les données sous forme de table de tas.
hqt
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.