Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Masalah kinerja kueri MySQL yang serius setelah menambahkan kondisi

Harap berikan SHOW CREATE TABLE .

Saya berharap untuk melihat indeks komposit ini:

`val`: (entityId, attributeId)   -- order is not critical

Sayangnya, karena code adalah LONGTEXT , ini tidak mungkin untuk entity :INDEX(type, code, entityId) . Karenanya ini tidak akan terlalu efisien:

        SELECT  entityId
            from  entity
            where  code = v9.Value
              and  type = 97
            limit  1

Saya melihat LIMIT dengan ORDER BY -- apakah Anda peduli dengan nilai yang Anda dapatkan?

Mungkin itu akan lebih baik ditulis sebagai

    WHERE EXISTS ( SELECT 1 FROM entity
                WHERE entityID = e3.entityID
                  AND code     = v9.Value
                  AND type = 97 )

(Apakah Anda yakin tentang campuran e3 dan v9 ?)

Membungkus...

Ini memaksa LEFT JOIN menjadi JOIN . Dan itu menghilangkan ORDER BY inner bagian dalam .

Kemudian Pengoptimal mungkin memutuskan yang terbaik untuk memulai dengan 68e9145e-43eb-4581-9727-4212be41bef5 , yang saya sebut val AS v11 :

JOIN val AS v11 ON (v11.entityId = e2.id
             and  v11.attributeId = 1614)
             AND  v11.Value = 'bar2')

Jika ini adalah tabel EAV, maka yang dilakukan hanyalah memverifikasi bahwa [, 1514] memiliki nilai 'bar2'. Ini sepertinya bukan ujian yang masuk akal.

selain rekomendasi saya sebelumnya.

Saya lebih suka EXPLAIN SELECT ... .

EAV

Dengan asumsi val adalah tabel EAV tradisional, ini mungkin akan jauh lebih baik:

CREATE TABLE `val` (
  `attributeId` int(11) NOT NULL,
  `entityId` int(11) NOT NULL,
  `Value` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
  PRIMARY KEY(`entityId`,`attributeId`),
  KEY `IX_val_attributeId` (`attributeId`),
) ENGINE=InnoDB AUTO_INCREMENT=2325375 DEFAULT CHARSET=latin1

Kedua ID tidak memiliki penggunaan praktis (kecuali saya kehilangan sesuatu). Jika Anda terpaksa menggunakannya karena kerangka kerja, itu sangat disayangkan. Mempromosikan (entityId, attributeId) menjadi PK membuat pengambilan value sedikit lebih cepat.

Tidak ada cara yang berguna untuk menyertakan LONGTEXT dalam indeks apa pun, jadi beberapa saran saya sebelumnya perlu diubah.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara mendapatkan hanya baris pertama dari ResultSet

  2. Bisakah Anda menggunakan peningkatan otomatis di MySql tanpa itu menjadi Kunci utama?

  3. MySQL max_allowed_packet reset

  4. MySQL - Penghitung dalam grup

  5. Beberapa Pengaturan Pusat Data Menggunakan Galera Cluster untuk MySQL atau MariaDB