Est-il possible de faire en sorte qu'InnoDB utilise des index identiques à MyISAM au lieu d'un index clusterisé en raison de la limitation de la RAM tout en bénéficiant de ses performances de concurrence?
Le gen_clust_index (index clusterisé) sous le capot d'InnoDB abrite des entrées de clés primaires ainsi que des rowids. Ce qui est intéressant à propos de l'utilisation de gen_clust_index est le fait que tous les index non uniques que vous créez auront toujours un rowid correspondant pour gen_clust_index d'une table. Ainsi, il existe toujours des recherches d'index double, une pour l'index secondaire et une pour gen_clust_index.
Toute tentative d'amélioration de la présentation d'une table ou d'une clé primaire est annulée en raison de gen_clust_index, ou au moins de résultats marginaux au mieux.
EXEMPLE
Certaines personnes tentent de trier un MyISAM dans l'ordre PRIMARY KEY. Selon MySQL Database Design and Tuning, page 236, paragraphe 7, sous le sous-titre "Stockage d'une table dans l'ordre des index":
Si vous récupérez fréquemment de grandes plages de données indexées dans une table ou triez systématiquement les résultats sur la même clé d'index, vous pouvez envisager d'exécuter myisamchk avec l'option --sort-records. En faisant cela, dites à MySQL de trier les données de la table dans le même ordre physique que l'index, et cela peut aider à accélérer ce type d'opérations. Vous pouvez également combiner l'instruction ALTER TABLE avec une option ORDER BY d'une colonne particulière pour obtenir les mêmes résultats.
Certes, cela fonctionne et fonctionne efficacement POUR MyISAM . Vous pouvez exécuter ALTER TABLE ... ORDER BY col1, col2, ..., coln contre InnoDB où les colonnes peuvent ou non être celles de la PRIMARY KEY. Cela ne produira pas des résultats plus rapides pour InnoDB car ... c'est vrai ... vous devez consulter le gen_clust_index à chaque fois.
Certaines personnes peuvent rendre le format de ligne du tableau FIXE à l'aide ALTER TABLE mydb.mytb ROW_FORMAT=Fixed;
et peuvent obtenir une augmentation de 20% des performances de lecture sans autres modifications. Cela fonctionne et fonctionne efficacement POUR MyISAM . Cela ne produira pas des résultats plus rapides pour InnoDB car ... c'est vrai ... vous devez consulter le gen_clust_index à chaque fois.
Vous pouvez effectuer les opérations suivantes sur une table InnoDB nommée mydb.mytb:
CREATE TABLE mydb.mytc LIKE mydb.mytb;
INSERT INTO mydb.mytc SELECT * FROM mydb.mytb ORDER BY col1,col2,...coln;
ALTER TABLE mydb.mytb RENAME mydb.mytd;
ALTER TABLE mydb.mytc RENAME mydb.mytb;
DROP TABLE mydb.mytd;
Cela mettra la table dans l'ordre rowid dans le gen_clust_index. Cela peut produire des résultats marginaux pour InnoDB au mieux parce que ... c'est vrai ... vous devez consulter le gen_clust_index à chaque fois.
Maintenant, soyons un peu ridicules. Il existe une interface NoSQL pour interroger (SELECT uniquement) MyISAM et InnoDB appelée l' interface HandlerSocket (anciennement appelée HANLDER) . Cela vous donne accès aux données qui vous permettent de contourner tous les protocoles SQL, ACID et MVCC . Bien que cela soit possible, à mon humble avis, trop compliqué pour coder et maintenir. AFAIK, rien dans print n'indique si l'interface HandlerSocket interagit avec gen_clust_index ou non.
En résumé, il existe de nombreuses façons d'écorcher un chat. Dans ce cas, vous ne pouvez pas mettre la main sur le chat (gen_clust_index). Je suppose que c'est pourquoi MyISAM continue d'exister pour ses performances de lecture, sa flexibilité dans l'ordre des tableaux, le format des lignes de tableau et les outils à l'appui. InnoDB restera conçu autour de sa nature conforme à ACID jusqu'à ce qu'une âme courageuse prenne le code source InnoDB et le transforme en quelque chose qui a le meilleur de MyISAM et InnoDB .
L' index cluster est peut-être la raison des performances de concurrence d'InnoDB sur les lecteurs de spin traditionnels.
L'accès à une ligne via l'index cluster est rapide car les données de ligne se trouvent sur la même page où mène la recherche d'index. Si une table est volumineuse, l'architecture d'index en cluster enregistre souvent une opération d'E / S disque par rapport aux organisations de stockage qui stockent les données de ligne à l'aide d'une page différente de l'enregistrement d'index. (Par exemple, MyISAM utilise un fichier pour les lignes de données et un autre pour les enregistrements d'index.)
Les E / S disque coûtent cher. La réduction de cet avantage est donc un énorme avantage pour améliorer la concurrence.
Si les E / S de disque commencent à devenir moins chères et moins goulot d'étranglement (par exemple, à mesure que la technologie SSD devient plus stable), Oracle peut décider de changer le fonctionnement des index InnoDB. Plus probablement, il restera le même, car la même technologie rendra moins problématique «la limitation de la RAM».
Réponse courte: Non.
InnoDB clusters via la clé primaire, et en l'absence d'une clé primaire, il sélectionne le premier index unique. En l'absence d'un index unique, il crée une clé cachée de 6 octets pour le clustering.
Lorsque vous avez la clé cachée de 6 octets, tous les index secondaires se réfèrent à cette clé, plutôt qu'aux pointeurs exacts vers les emplacements de ligne (comme dans MyISAM), vous vous retrouvez donc avec une traversée de clé secondaire, puis une traversée de clé primaire pour trouver vos enregistrements .
Pour extrapoler un peu à partir de votre question, je suppose que vous vous inquiétez de la mémoire adaptée à un arbre, car pour rechercher efficacement, tous les nœuds racine doivent être en mémoire, car vous devez toujours suivre ce chemin pour trouver vos pages de feuilles?
C'est vrai, mais une consolation est que les bases de données commerciales essaient de rendre leurs arbres aussi gros que possible, plutôt que profonds. Essayez d'exécuter xtrabackup --stats sur vos données pour voir. Par exemple:
<INDEX STATISTICS>
table: test/table1, index: PRIMARY, space id: 12, root page 3
estimated statistics in dictionary:
key vals: 25265338, leaf pages 497839, size pages 498304
real statistics:
level 2 pages: pages=1, data=5395 bytes, data/pages=32%
level 1 pages: pages=415, data=6471907 bytes, data/pages=95%
leaf pages: recs=25958413, pages=497839, data=7492026403 bytes, data/pages=91%
Il y avait 497839 pages foliaires (~ 8 Go), mais seulement 416 pages ci-dessus (6,5 Mo). J'ai exécuté cette commande plusieurs fois sur les données de production, et cela me surprend toujours lorsque j'ai des millions de milliards d'enregistrements, et seulement des pages de niveau 1 à 3 + feuilles.