Il existe de nombreux articles exagérant (à mon humble avis bien sûr) la nécessité de innodb_file_per_table
. Je comprends qu'avec innodb_file_per_table
, Il devrait y avoir un meilleur contrôle sur les tables individuelles; comme sauvegarder chaque table séparément. Cependant, la revendication d'une meilleure performance est discutable.
Dans mon test, il n'y a pas de différence de performances entre innodb_file_per_table
Et ibdata1
Pour une base de données de 60 Go. Bien sûr, c'était un test simple avec des requêtes normales, et la situation peut être différente pour des requêtes compliquées dans la vie réelle (c'est la raison pour laquelle j'ai posé cette question). Linux 64 bits avec ext4
Peut gérer efficacement les fichiers volumineux.
Avec innodb_file_per_table
, Davantage d'opérations d'E/S disque sont nécessaires; et ceci est significatif dans les contraintes JOIN
s et FOREIGN KEY
compliquées.
L'espace disque logique est partagé sur un seul ibdata
; comment des espaces de table dédiés pour des tables distinctes peuvent économiser de l'espace disque? Bien sûr, il est plus facile de libérer de l'espace table pour chaque table avec ALTER
, mais c'est toujours un processus coûteux (avec verrouillage de table).
QUESTION: Est-ce que innodb_file_per_table
A un effet sur une meilleure performance de mysql? Si oui, pourquoi?
Je ne pense pas que ce soit une question de performance mais de gestion.
Avec un fichier séparé par table, vous pouvez par exemple stocker différentes bases de données dans différents périphériques de stockage.
Vous pouvez traiter le cas de très grandes bases de données dans des systèmes de fichiers qui ne peuvent pas gérer de gros fichiers (au moins reporter le problème jusqu'à ce qu'une table atteigne la limite de taille de fichier).
Vous n'avez pas de croissance d'espace de table incontrôlée. Si vous avez de grandes tables que vous supprimez, le fichier ibdata
reste petit.
Un aspect qui peut avoir un certain effet sur les performances est la fragmentation des données de table et des index, qui sera limitée par table. Mais cela nécessite des tests pour être confirmé.
Pourquoi utiliser innodb_file_per_table?
Parce qu'il est plus facile à gérer individuellement car cela peut être fait au niveau du fichier. Cela signifie que même si le serveur est en panne, vous pouvez toujours copier des données en copiant les fichiers de table alors que l'utilisation d'un espace table partagé signifie soit copier tout qui peut être inutilement massif, soit trouver un moyen pour faire fonctionner le serveur pour extraire des données (vous ne voulez vraiment pas extraire manuellement les données avec un éditeur hexadécimal).
Quelqu'un a préven que vous ne pouvez pas simplement copier et coller des fichiers .ibd
D'un serveur à un autre. Cela peut être vrai, mais cela ne devrait pas s'appliquer aux sauvegardes sur le même serveur (j'utilise le terme sauvegarde ici dans le sens traditionnel de faire une copie; c'est-à-dire, ne pas changer radicalement le tout). De plus, ibdata1
Est automatiquement recréé au démarrage (comme vu dans l'étape supprimer ibdata1
de la plupart des guides de "conversion en fichier par table"). En tant que tel, vous avez pas besoin de copier ibdata1
En plus de vos fichiers .ibd
(Et leurs fichiers .frm
, Etc. correspondants) .
Si vous essayez de récupérer une table perdue, il devrait être suffisant de copier ses fichiers .ibd
Et .frm
, Ainsi que information_schema
(Qui est beaucoup plus petit que ibdata1
). De cette façon, vous pouvez les mettre dans un serveur factice et extraire votre table sans avoir à copier le tout, chose massive.
Cependant, la revendication d'une meilleure performance est discutable. … Avec innodb_file_per_table, davantage d'opérations d'E/S disque sont nécessaires; et ceci est significatif dans les contraintes complexes JOIN et FOREIGN KEY.
Sans surprise, les performances dépendront entièrement de la ou des bases de données spécifiques utilisées. Une personne aura (même considérablement) des résultats différents d'une autre.
Il est vrai qu'il y aura plus d'opérations d'E/S disque avec fichier par table, mais seulement légèrement plus. Pensez au fonctionnement du système.
Pour une base de données monolithique:
ibdata1
Est ouvertibdata1
Déjà ouvertPour une base de données par table:
ibdata1
Est ouvert.ibd
Est ouvert.ibd
.ibd
Déjà ouvertVous remarquerez que lorsque le serveur est en cours d'exécution, vous ne pouvez pas déplacer les fichiers de données car le serveur a des poignées ouvertes vers eux. En effet, quand il démarre, il les ouvre et les laisse ouverts. Il ne les ouvre et ne les ferme pas pour chaque requête individuelle.
En tant que tel, il n'y a que quelques opérations d'E/S supplémentaires au début, lorsque le serveur démarre; pas pendant qu'il fonctionne. De plus, bien que chaque fichier .ibd
Individuel ait sa propre surcharge distincte (signatures de fichier, structures, etc.), ils sont mis en cache en mémoire et ne sont pas relus pour chaque requête. De plus, les mêmes structures sont lues même avec un espace table partagé, il n'y a donc pratiquement pas (voire pas du tout) de mémoire supplémentaire requise.
Innodb_file_per_table a-t-il un effet sur une meilleure performance de mysql?
En fait, si quoi que ce soit, la performance peut en fait être pire .
Lorsque vous utilisez un espace table partagé, les opérations de lecture et d'écriture peuvent parfois/souvent être combinées de sorte que le serveur lit un échantillon de données de plusieurs tables en une seule fois depuis ibdata
.
Cependant, si les données sont réparties sur plusieurs fichiers, il doit alors effectuer une opération d'E/S distincte pour chacun individuellement.
Bien sûr, cela dépend à nouveau entièrement de la base de données en question; l'impact sur les performances réelles dépendrait de la taille, de la fréquence des requêtes et de la fragmentation interne de l'espace table partagé. Certaines personnes peuvent remarquer une grande différence tandis que d'autres peuvent ne pas voir d'impact du tout.
L'espace disque logique est partagé sur des ibdata uniques; comment des espaces de table dédiés pour des tables distinctes peuvent économiser de l'espace disque?
Ce ne est pas. Si quoi que ce soit, il augmente l'utilisation du disque .
Je n'ai pas de base de données de 60 Go pour tester, mais ma base de données personnelle "dérisoire" qui contient mon WordPress et quelques petites tables pour un usage personnel et des tests de développement pesait environ 30 Mo) tout en utilisant un espace table partagé. Après l'avoir converti en fichier par table, il a gonflé à ~ 85 Mo. Même en supprimant tout et en réimportant, il restait> 60 Mo.
Cette augmentation est due à deux facteurs:
La taille minimale absolue pour ibdata1
Est - pour une raison quelconque - 10 Mo, même si vous n'avez que information_schema
Stocké en elle.
Avec un espace table partagé, seul ibdata1
A des frais généraux comme les signatures de fichiers, les métadonnées, etc., mais avec chaque table, chaque fichier .ibd
Individuel a tout cela. Cela signifie que le total (même avec une hypothétique <10 Mo ibdata1
) Serait un peu plus élevé d'au moins:
GetTotalSizeofOverhead() * GetNumTables()
Évidemment, cela ne va pas être énorme augmente (sauf si vous utilisez un hôte qui limite la taille de votre base de données ou les stockez sur un lecteur flash, etc.), mais ce sont néanmoins des augmentations, et tandis qu'en basculant ( tous les) table vers fichier par table, vous pouvez réduire ibdata1
à 10 Mo, le total global sera invariablement plus = qu'il ne l'était.
C'est ma raison pour TOUJOURS utiliser innodb_file_per_table:
Sans fichier par table, le fichier ibdata ne compresse, ne rétrécit ou ne diminue jamais dans l'espace. Pas lorsque vous supprimez une ligne, supprimez une table ou une base de données. 2 Go de données peuvent devenir un fichier de 20 Go en un rien de temps si vous avez un système de mise en file d'attente actif.
Supposons que vous souhaitiez effectuer une sauvegarde de votre table actuelle de 1 Go avant une modification, puis la supprimer ensuite. Vous êtes coincé avec un Go d'espace désormais inutilisé dans votre ibdata. Bummer.
Il existe probablement d'innombrables exemples de cas où des mesures temporaires gonflent le fichier de données unique, mais il suffit de dire qu'à mon avis, il n'y a jamais de raison de NE PAS utiliser innodb_file_per_table
En outre, voici un bon article à lire: http://code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table
Ma raison pour laquelle ne pas utiliser innodb_file_per_table est la performance.
J'ai fait quelques tests pour notre base de données avec 450 tables sur mysql 5.5.45 Linux CentOS version 6.7
Pour tests unitaires qui insère les appareils dans la base de données avant chaque test (n'utilisant pas toutes les tables à chaque fois) et qui se teste lui-même, cela fonctionne beaucoup avec la base de données (insertions, mise à jour, suppressions, sélection)) les performances étaient 3 à 5 fois supérieures lorsque les tables de base de données n'étaient pas séparées en plusieurs fichiers.
Je recommande de tester votre base de données avec les requêtes que vous souhaitez utiliser et de la comparer avant de décider d'utiliser innodb_file_per_table
Vous pouvez peut-être découvrir que pour le serveur de production, vous pouvez utiliser innodb_file_per_table mais pour l'environnement CI (continue l'intégration) qui démarre les tests unitaires (utilise beaucoup DB) et aussi les développeurs qui commencent beaucoup les tests unitaires est préférable de ne pas l'utiliser en raison des performances.
Selon l'article ci-dessous, les performances ne concernent pas la gestion des données (opérations crud elles-mêmes), mais plutôt la création et la suppression d'objets.
innodb_file_per_table rend la création massive et la suppression d'objets plus lentes que le stockage ibdata et pour la production n'est pas applicable mais pour un test continu devrait être pertinent.
https://www.percona.com/blog/2015/02/24/mysqls-innodb_file_per_table-slowing/
Cela rend les données plus faciles à gérer car vous pouvez récupérer de l'espace inutilisé, ce qui est agréable.
Je pense que si votre base de données est utilisée principalement pour certaines requêtes, cela n'affectera pas beaucoup les performances. Il doit toujours lire la même quantité de données. Je ne pense pas que les fichiers dont il lit les données importent beaucoup.
Cependant, cela peut aggraver les performances sur une base de données qui effectue de nombreuses insertions et mises à jour. En effet, mysql appelle fsync () sur le fichier de stockage après avoir validé une transaction. S'il n'y a qu'un seul fichier, il passe un appel et attend que l'appel se termine. S'il y a beaucoup de fichiers, il doit effectuer l'appel plusieurs fois et attendre que tous ces appels reviennent avant que la commande commit ne puisse revenir.
Voici un article de quelqu'un qui a rencontré ce problème: http://umangg.blogspot.com/2010/02/innodbfilepertable.html
À mon humble avis, il vaut mieux utiliser innodb_file_per_table, il est plus sécurisé. Si vous ne l'utilisez pas, vous pourriez avoir un problème sur les systèmes FAT32 où seulement 4 Go de fichiers sont autorisés. J'ai écrit un article à ce sujet en langue slovaque ( https://www.itsoft.sk/preco-sa-neuvolni-miesto-na-disku-po-zmazani-mysql-tabulky/ ).