web-dev-qa-db-fra.com

Quelles requêtes sont plus rapides avec Postgers qu'avec MySQL InnoDB

J'ai lu différence de performance entre MySQL et PostgreSQL pour le même schéma/requêtes . Voici une brève rétention de l'article:

Les tables PostgreSQL sont des tables de tas ( signifie Aucun index clustered) ... une recherche de clé primaire pour A ( postgres) Table nécessite de frapper l'index, de rechercher Emplacement dans le fichier puis appuyez sur la table de tas et tirez l'enregistrement. Cela signifie un certain nombre de pièces d'E/S aléatoire d'E/S ... InnoDB utilise une approche différente. Avec Innodb, la table est un indice B-Tree ( clustered, triée physiquement) ... Moins de disques aléatoires E/S est requis pour la recherche PK ... En même temps, un index Le balayage nécessite une traversée de deux index au lieu d'un ( Index -> Index PK -> Table rangée), Signification Utilisation de tout index autre que la clé principale finale étant plus lente et les scans séquentiels sont encore plus lents.

quel type de requêtes sont beaucoup plus rapides avec Postgers qu'avec MySQL Innodb ?

Je comprends pourquoi la recherche pk est beaucoup mieux pour MySQL. Je ne comprends pas:

  1. Pourquoi rechercher deux index (Innodb, recherche via un indice non PK) est beaucoup plus lent? Cela nécessite-t-il deux fois plus d'E/S ou CPU? Peut-il compenser cet énorme avantage de PK Recherche Boost?
  2. Pourquoi les analyses séquentielles innodb sont plus lentes?

P.s. Internet dit que Postgres est meilleur pour les requêtes complexes et la sous-substance, mais je ne comprends toujours pas pourquoi est-ce mieux?

6
VB_

Pour éviter la guerre de la flamme, je vais simplement regarder la façon dont chaque œuvre de stockage sur interrographique, pas vraiment une référence. Je vais utiliser cette table comme référence (le code doit être légèrement modifié pour exécuter sur les deux RDBMS):

CREATE TABLE employees (
    emp_id int,
    name varchar,
    depto_no int,
    salary decimal,
    CONSTRAINT emp_pk PRIMARY KEY (emp_id);
);
CREATE INDEX emp_depto_idx ON employees (depto_no);

Sur PostgreSQL, il y aura 3 structures:

  1. Le tas employees, qui est essentiellement la table stockée séquentiellement (comme vous imaginez une table)
  2. Le emp_pk Index (qui est également la clé primaire), stockée en tant qu'index B-Tree où chaque élément comporte un pointeur sur le tas employee 'S, avec la page exacte/décalage dans le disque
  3. Le emp_depto_idx index, c'est comme emp_pk, un arbre B avec des pointeurs vers le tas, sauf qu'il n'applique pas l'unicité

Sur MySQL Innodb, il n'y aura que deux:

  1. emp_pk et employees _ sera stocké comme une structure, un arbre B commandé par emp_id colonne et conservent simplement la valeur sur les autres colonnes comme chargee de la charge dans les nœuds de feuilles.
  2. emp_depto_idx L'index est un arbre B qui sur chaque élément, il aura le emp_id Valeur référencée de cette ligne (pas un pointeur d'emplacement physique).

Recherche principale

pourquoi pk recherche est beaucoup mieux pour mysql

Je sais que vous savez que, mais expliquons clairement.

Quand vous l'interrogeez comme:

SELECT * FROM employees WHERE emp_id = 10;

Sur PostgreSQL, il peut naviguer sur emp_pk index (une analyse sur l'index de l'arborescence B, puis obtenir la page/décalage pour obtenir la ligne de référencement à partir de employees tables de tas (One Direct Page/Row Fetch, pas vraiment une analyse). Donc, ne analyse sur l'index et une récupération directe sur le tas.

Sur MySQL, il ne fera que naviguer dans l'index de clé primaire (une analyse sur l'indice B B-Tree), car toutes les informations sont déjà présentes, aucune autre recherche n'est requise. Donc, juste ne analyse sur l'index.

Ainsi, tandis que PostgreSQL a besoin de faire une balayage et une excellente récupération, MySQL vient de faire une analyse.

Recherche d'index secondaire

Pourquoi rechercher deux index (Innodb, recherche via un indice non PK) est beaucoup plus lent? Cela nécessite-t-il deux fois plus d'E/S ou CPU? Peut-il compenser cet énorme avantage de PK Recherche Boost?

Maintenant, supposons cette autre requête:

SELECT * FROM employees WHERE depto_no = 14;

Sur PostgreSQL, cela ne sera pas très différent de l'autre. Il scannera emp_depto_idx Et puis, pour chaque ligne renvoyée, récupérez la valeur directement du tas. Donc, ne analyse sur l'index et une récupération directe sur le tas pour chaque ligne correspondante.

Sur mysql, il scannera le emp_depto_idx (une analyse sur l'index), alors, pour chaque ligne renvoyée, il obtiendra le référencement emp_id et numériser l'index de clé principal. Donc, ne analyse sur un indice secondaire et une analyse de l'indice principal de chaque ligne correspondante.

Regarde la différence? Alors que PostgreSQL fera une analyse, puis récupérez chaque ligne correspondante avec un pointeur direct, InnoDB fera d'abord une analyse similaire, puis une autre numérisation pour chaque ligne correspondante. Maintenant, cela peut être suffisamment rapide si le département 14 a peu d'employés, mais vraiment lentement, car il obtient plus d'employés (bien sûr, il sera plus lent sur les deux PDBM, mais la courbe est probablement Plus haut avec InnoDB ).

Scan complet

Pourquoi les analyses séquentielles innodb sont plus lentes?

Réponse simple, car ce n'est pas vraiment "séquentiel" ...

Eh bien, voyons la requête la plus simple (et certainement lente):

SELECT * FROM employees;

Sur PostgreSQL, il peut être simple de numériser le tout employees tas, la rangée à la ligne, dans son ordre séquentiel physique (peu importe l'ordonnance d'insertion ici, quelle est la manière dont les tuples et les pages sont physiquement organisés maintenant).

Sur InnoDB, il doit parcourir l'index, ce qui signifie plus de scans aléatoires (car les pages d'index ne sont pas nécessairement commandées physiquement et logiquement de la même manière).

Si vous pensez de disques magnétiques, la différence est assez évidente, c'est savoir que l'accès séquentiel est plus rapide que l'accès aléatoire. Pour les SSDS, ce n'est pas nécessairement vrai, bien que des avantages soient toujours des avantages sur l'accès séquentiel, comme lire-devant. Donc, dans la plupart des scénarios, la balayage complète de PostgreSQL sera probablement plus rapide que Innodb, du moins pour de grandes tables considérables (avis que je n'ai pas défini ce qui est "grand", vous devez l'essayer et voir où cette différence importe vraiment, il peut tout simplement pas matière dans de nombreux cas). Le meilleur, pour les deux RDBM, est de concevoir votre modèle et vos requêtes pour éviter les analyses complètes, si possible.

Questions complexes

Internet dit que Postgres est meilleur pour les requêtes complexes et la sous-substance, mais je ne comprends toujours pas pourquoi est-ce mieux?

C'est un énorme sujet et probablement celui qui générerait plus de guerre de flamme, alors je vais simplement vous donner quelques exemples. Il est courant de dire que PostgreSQL est préférable pour les requêtes complexes, et il peut être vrai si vous pensez que vous pensez sur ses capacités de requête qui ne sont pas présentes dans MySQL (ne pas encore envisager la performance), comme:

  • Expression de table commune (CTE)
  • Fonctions de fenêtre
  • Jointures latérales
  • Tableaux
  • Types JSON, Fonctions et opérateurs
  • etc.

En outre, il existe de nombreuses différences dans le planificateur et exécuteur de ces deux. Par exemple, PostgreSQL peut faire des jointures à l'aide de boucles imbriquées, de jointures de hachage et de jointures de fusion, tandis que MySQL ne peut faire que à l'aide de boucles imbriquées. Malgré cela, MySQL a de nombreuses optimisations dans ses algorithmes de boucle imbriqués et PostgreSQL a un choix plus difficile sur son planificateur, et parfois cela fait une erreur (mais les mysqls).

Derniers mots

Cette réponse est juste un coup d'œil vraiment rapide sur le sujet, il reste encore beaucoup de choses à prendre en compte pour ces deux SDBM lorsqu'il s'agit de la performance, comme un balayage à l'index, un vide vs annuler, un parallélisme, etc. La vérité est que vous pouvez ' t simple dire que l'on est plus rapide que l'autre, il est clair pour moi (c'est-à-dire à vous?) Pour que l'on puisse être plus rapide dans certains environnements, tandis que l'autre peut être plus rapide dans d'autres.

17
MatheusOl