Verbessern Sie die Leistung von MYSQL-Abfragen mit Eins-zu-Viele-Beziehungen
P粉993712159
P粉993712159 2024-03-28 23:17:19
0
1
461

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粉993712159
P粉993712159

Antworte allen(1)
P粉226667290

通过创建以下索引,我能够在测试中获得更有利的 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 使用地点;使用索引;独特
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage