"CRÉER UN INDEX" dans MySQL est-il une opération linéaire?


20

Ce que je veux dire, c'est ce qui suit:

Si la création d'un index sur une table avec des nlignes prend du ttemps. La création d'un index sur la même table 1000*nprendra environ du 1000*ttemps.

Ce que j'essaie de réaliser, c'est d'estimer le temps nécessaire pour créer l'index sur la base de données de production en créant le même index sur la base de données de test beaucoup plus petite.

Réponses:


16

La création d'index est essentiellement une opération de tri , donc elle a au mieux une complexité de croissance de l'ordre n log nen moyenne (vous pourriez trouver qu'elle fait mieux dans certains cas, et n'est pas susceptible de faire bien pire).

Si toutes vos pages de données pertinentes s'insèrent dans la RAM et sont déjà dans la RAM, et l'index s'adaptera également, et votre SGBD ne force pas l'écriture des pages d'index avant la fin de la création (les blocs d'index ne sont donc pas mis à jour plusieurs fois sur le disque pendant l'opération), alors la vitesse d'écriture de l'index résultant sur le disque sera plus importante que le temps nécessaire pour effectuer le tri - vous pourriez donc vous rapprocher d'une relation linéaire entre le nombre de lignes et le temps nécessaire à la création de l'index - mais si vous supposez le pire des cas, vous risquez moins d'être désagréablement surpris!

N'oubliez pas qu'à moins que vous n'interrompiez l'accès à la base de données de production pendant l'opération, tout index créé sera en concurrence pour la bande passante d'E / S et / ou les verrous avec d'autres activités, vous devriez donc essayer de tenir compte de cela si vous effectuez vos tests d'estimation de synchronisation sur un autre système même s'il est configuré de manière identique.


7

Il convient également de noter que si vous pouvez séparer les broches des index des broches de la table, vous pourrez travailler à partir de deux disques à la fois (toujours limité à la vitesse du contrôleur de disque au milieu, si un RAID ou similaire, mais ce sera toujours plus rapide qu'un disque).

Je me rends compte que la création d'un index n'est pas complètement une opération simul-lecture-écriture, mais cela accélère considérablement les choses.

CAVEATS: Je suis moi-même un gars MSSQL, et donc je ne suis pas sûr de MySQL, mais je dois imaginer que le concept de fractionnement des broches n'est pas spécifique à SQLServer et Oracle (où j'en ai entendu parler là-bas aussi, IIRC ). Je ne saurais tout simplement pas comment mettre en place ce concept. Mais en termes SQLServer, cela signifierait avoir un groupe de fichiers séparé en plus PRIMARYet placer les index sur l'autre groupe de fichiers, avec l'autre groupe de fichiers affecté à un ensemble de broches n'impliquant pas PRIMARY(le placement de la broche par rapport aux groupes de fichiers est une autre histoire)


1
À peu près la même chose dans Oracle - seuls les groupes de fichiers sont appelés un tablespace
Joe


1

Ça dépend.

Variable # 1: Si MySQL choisit de construire le (s) index (s) à la volée, ou d'attendre que toutes les données soient entrées, alors faites un tri, etc., pour construire l'index. Remarque: les index UNIQUE (je pense) doivent être construits à la volée afin que l'UNIQUEness puisse être vérifié. La CLÉ PRIMAIRE pour InnoDB est stockée avec les données (ou vous pouvez l'indiquer vice versa), de sorte que DOIT être construit de manière aléatoire.

Variable # 2: L'index suit les données (par exemple AUTO_INCREMENT ou horodatage) par rapport à aléatoire (GUID, MD5), ou quelque part entre les deux (numéro de pièce, nom, friend_id).

Variable # 3 (si l'index est construit à la volée): l'index peut tenir dans le cache (key_buffer ou innodb_buffer_pool), ou il peut se répandre sur le disque.

Les index qui suivent les données sont efficaces et pratiquement linéaires, quelle que soit la réponse à # 1.

Les identifiants aléatoires sont une douleur. Si l'index ne tient pas dans le cache, le temps de le construire sera bien pire que linéaire, quelles que soient les autres variables. (Je ne suis pas d'accord avec Rolando dans ce cas.) Une énorme table InnoDB avec un GUID pour le PK est douloureusement lente à INSÉRER - planifiez 100 lignes / sec pour les disques ordinaires; peut-être 1000 si vous avez des SSD. LOAD DATA et batch INSERTs ne vous permettront pas de dépasser la lenteur du stockage aléatoire.

3,53 à 5,6 - peu de choses ont changé.

Plusieurs broches? L'entrelacement RAID est meilleur dans presque toutes les situations que d'attribuer manuellement ceci ici et cela là-bas. Le fractionnement manuel conduit à des situations déséquilibrées - une analyse de table est bloquée sur le disque de données; une opération d'index uniquement est bloquée sur le disque d'index; une requête isolée frappe d'abord le disque d'index, puis le disque de données (pas de chevauchement); etc.

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.