Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Poważne problemy z wydajnością zapytań MySQL po dodaniu warunku

Proszę podać SHOW CREATE TABLE .

Mam nadzieję, że zobaczę te indeksy złożone:

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

Niestety, ponieważ code to LONGTEXT , nie jest to możliwe dla entity :INDEX(type, code, entityId) . Dlatego nie będzie to bardzo wydajne:

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

Widzę LIMIT z ORDER BY -- czy obchodzi Cię, jaką wartość otrzymujesz?

Prawdopodobnie lepiej byłoby napisać to jako

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

(Czy jesteś pewien kombinacji e3 i v9 ?)

Zawijanie...

Wymusza to LEFT JOIN zostać JOIN . I pozbywa się wtedy wewnętrznego ORDER BY .

Wtedy Optymalizator prawdopodobnie zdecyduje, że najlepiej zacząć od 68e9145e-43eb-4581-9727-4212be41bef5 , który nazywam val AS v11 :

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

Jeśli jest to tablica EAV, to wszystko, co robi, to sprawdzenie, czy [, 1514] ma wartość 'bar2'. Nie wydaje się to rozsądnym testem.

oprócz mojej poprzedniej rekomendacji.

Wolałbym EXPLAIN SELECT ... .

EAV

Zakładając val to tradycyjna tabela EAV, prawdopodobnie byłaby znacznie lepsza:

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

Te dwa identyfikatory nie mają praktycznego zastosowania (chyba że czegoś mi brakuje). Jeśli jesteś zmuszony do ich używania ze względu na ramy, to jest to niefortunne. Promowanie (entityId, attributeId) jako PK powoduje pobranie value trochę szybciej.

Nie ma użytecznego sposobu na dołączenie LONGTEXT w dowolnym indeksie, więc niektóre z moich poprzednich sugestii wymagają zmiany.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Policz wiersze o tym samym identyfikatorze w php

  2. Pozwól, aby liczba zaczynała się od ZERA, gdy jest przechowywana w polu mysql integer

  3. Odmowa dostępu do mysql dla użytkownika (zdarza się tylko przy połączeniu przez php)

  4. gcc nie kompiluje i nie uruchamia bibliotek MySQL C

  5. Partycjonowanie i łączenia MySQL