Maison  >  Questions et réponses  >  le corps du texte

Améliorez les performances des requêtes MYSQL avec des relations un-à-plusieurs

J'ai une requête dans ma base de données qui prend 25 secondes pour renvoyer des résultats, ce qui est beaucoup trop long. Il semble que cela devrait être assez simple. Deux tables : la table principale (document) est une table standard avec quelques colonnes de données et la table de connexion est une table de mappage avec seulement deux colonnes (parent_id, division_id). Auparavant, il n'y avait pas d'index sur la table de mappage, j'ai donc ajouté un index et modifié "l'interprétation" pour inclure l'index, mais cela ne semble avoir aucun impact sur les performances.

La requête ressemble à ceci :

explain SELECT DISTINCT doc.*  
FROM document doc  
LEFT JOIN multi_division_mapper divisions ON doc.id = divisions.parent_id  
WHERE doc.clientId = 'SOME_GUID'  
AND (divisions.division_id IS NULL OR divisions.division_id  IN ('SOME_GUID'));

Le résultat de l'explication est :

Nombre total de lignes dans le document : 6720 Nombre total de lignes dans le mappeur : 6173

Sur la base des informations que j'ai recueillies, je dois améliorer "type" ou "extra" pour rendre la requête plus rapide. Que puis-je faire ici ?

Créer une instruction de tableau :

CREATE TABLE `document` (
   `id` varchar(36) NOT NULL,
   `addedBy` varchar(255) DEFAULT NULL,
   `addedDate` datetime NOT NULL,
   `editedBy` varchar(255) DEFAULT NULL,
   `editedDate` datetime NOT NULL,
   `deleted` bit(1) DEFAULT NULL,
   `clientId` varchar(36) NOT NULL,
   `departmentId` varchar(36) DEFAULT NULL,
   `documentParentId` varchar(36) DEFAULT NULL,
   `documentParent` varchar(50) DEFAULT NULL,
   `fileId` varchar(255) DEFAULT NULL,
   `fileUrl` varchar(600) DEFAULT NULL,
   `documentName` varchar(500) NOT NULL,
   `displayName` varchar(255) NOT NULL,
   `documentId` varchar(45) DEFAULT NULL,
   `notes` varchar(1000) DEFAULT NULL,
   `visibility` varchar(45) NOT NULL DEFAULT 'PRIVATE',
   `documentType` varchar(45) NOT NULL,
   `restrictDelete` bit(1) NOT NULL,
   `customData` text,
   `releaseDate` datetime NOT NULL,
   `expirationDate` datetime NOT NULL,
   `isApproved` bit(1) NOT NULL DEFAULT b'0',
   `userSupplier` varchar(36) DEFAULT NULL,
   `complianceCertificateId` varchar(36) DEFAULT NULL,
   `Status` varchar(50) DEFAULT 'NEUTRAL',
   PRIMARY KEY (`id`),
   KEY `idx_client` (`clientId`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 CREATE TABLE `multi_division_mapper` (
    `parent_id` varchar(36) NOT NULL,
    `division_id` varchar(36) NOT NULL,
    PRIMARY KEY (`parent_id`,`division_id`),
    KEY `idx_parent` (`parent_id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

P粉993712159P粉993712159204 Il y a quelques jours435

répondre à tous(1)je répondrai

  • P粉226667290

    P粉2266672902024-03-29 13:06:40

    J'ai pu obtenir un rapport EXPLAIN plus favorable dans mes tests en créant l'index suivant :

    ALTER TABLE multi_division_mapper
      DROP INDEX idx_parent,
      ADD INDEX (division_id, parent_id);

    J'ai également supprimé idx_parent car c'était redondant ; c'est le préfixe de la clé primaire.

    répondre
    0
  • Annulerrépondre
  • id Sélectionnez le type Table Partition Type Clés possibles Clé key_len Référence OK Filtré Extra
    1 Simple Documentation vide Référence idx_client idx_client 110 Constante 1 100.00 Utiliser temporaire
    1 Simple Département vide Référence main,division_id ID du département 38 Constante 1 100.00 Utilisez l'emplacement ; utilisez l'index ;