Tingkatkan prestasi pertanyaan MYSQL dengan perhubungan satu-ke-banyak
P粉993712159
P粉993712159 2024-03-28 23:17:19
0
1
464

Saya mempunyai pertanyaan dalam pangkalan data saya yang mengambil masa 25 saat untuk mengembalikan hasil, yang terlalu panjang. Nampaknya ia sepatutnya agak mudah. Dua jadual; jadual utama (dokumen) ialah jadual standard dengan beberapa lajur data, dan jadual sambungan ialah jadual pemetaan dengan hanya dua lajur (id_ibu bapa, id_bahagian). Sebelum ini tiada indeks pada jadual pemetaan, jadi saya menambah indeks dan menukar "tafsiran" untuk memasukkan indeks, tetapi ia nampaknya tidak memberi kesan kepada prestasi.

Pertanyaan kelihatan seperti ini:

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

Hasil penjelasan ialah:

Jumlah bilangan baris dalam dokumen: 6720 Jumlah bilangan baris dalam pemeta: 6173

Berdasarkan maklumat yang saya kumpul, saya perlu menambah baik "jenis" atau "tambahan" untuk membuat pertanyaan lebih cepat. Apa yang boleh saya buat di sini?

Buat pernyataan jadual:

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

membalas semua(1)
P粉226667290

Saya dapat mendapatkan laporan EXPLAIN yang lebih baik dalam ujian saya dengan mencipta indeks berikut:

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

Saya juga mengalih keluar idx_parent kerana ia berlebihan; ia adalah awalan untuk kunci utama.

id Pilih jenis Meja Partition Taip Kunci yang mungkin Kunci key_len Rujukan OK Ditapis Tambahan
1 Mudah Dokumentasi kosong Rujukan idx_client idx_client 110 Malar 1 100.00 Guna sementara
1 Mudah Jabatan kosong Rujukan utama,id_bahagian ID Jabatan 38 Malar 1 100.00 Gunakan lokasi;
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan