Heim  >  Fragen und Antworten  >  Hauptteil

Verbessern Sie die Leistung von MYSQL-Abfragen mit Eins-zu-Viele-Beziehungen

Ich habe eine Abfrage in meiner Datenbank, die 25 Sekunden benötigt, um Ergebnisse zurückzugeben, was viel zu lang ist. Es scheint, als ob es ziemlich einfach sein sollte. Zwei Tabellen; die Haupttabelle (Dokument) ist eine Standardtabelle mit einigen Datenspalten und die Verbindungstabelle ist eine Zuordnungstabelle mit nur zwei Spalten (parent_id, Division_id). Zuvor gab es keinen Index für die Zuordnungstabelle, also habe ich einen Index hinzugefügt und die „Interpretation“ geändert, um den Index einzuschließen, aber es scheint keine Auswirkungen auf die Leistung zu haben.

Die Abfrage sieht so aus:

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'));

Das Ergebnis der Erklärung ist:

Gesamtzahl der Zeilen im Dokument: 6720 Gesamtzahl der Zeilen im Mapper: 6173

Basierend auf den Informationen, die ich gesammelt habe, muss ich „Typ“ oder „Extra“ verbessern, um die Abfrage schneller zu machen. Was kann ich hier tun?

Tabellenauszug erstellen:

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 Tage vor436

Antworte allen(1)Ich werde antworten

  • P粉226667290

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

    通过创建以下索引,我能够在测试中获得更有利的 EXPLAIN 报告:

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

    我还删除了 idx_parent 因为它是多余的;它是主键的前缀。

    id 选择类型 分区 类型 可能的键 key_len 参考 已过滤 额外
    1 简单 文档 参考 idx_client idx_client 110 常量 1 100.00 使用临时
    1 简单 部门 参考 主要,division_id 部门 ID 38 常量 1 100.00 使用地点;使用索引;独特

    Antwort
    0
  • StornierenAntwort