Autor Zpráva
JiricekXXX
Profil *
Dobrý den,

nemohu přijít na to, proč dotaz na DB trvá cirka 2s.

V záznamu je cca 120 tis položek.

SELECT SQL_NO_CACHE object.id, object.name, object.url, object.sb FROM objects
WHERE (active=1 OR (instock=1 OR inotherstock=1))
AND( (category=3) OR (category=1502) OR (category=631) OR (category=1444) OR (category=1119) 
(category=34) OR (category=1902) OR (category=231) OR (category=1424) OR (category=119)
(category=223) OR (category=152) OR (category=1611) OR (category=144) OR (category=111) )
AND name NOT LIKE '%(BESTSELLER)%' AND object.price>10000
ORDER BY stock DESC, date DESC

pole active, instock, inotherstock, category..má indexy
id je primary key/AI

všiml jsem si, že pokud vyhodím (tučně zvýrazněné (active=1 OR (instock=1 OR inotherstock=1))
a
AND( (category=3) OR (category=1502) OR (category=631) OR (category=1444) OR (category=1119) )

tak je to cca na 0,9s (i tak je to hodně)
blaaablaaa
Profil
JiricekXXX:
Stačí před dotaz dát EXPLAIN a sql vysvětlí, kolik stojí která část dotazu.
Kajman
Profil
Souhlasím, prozkoumejte výsledek explain.

Přijde mi, že v dotazu chybí 2x OR (začátek řádků 4 a 5).

Mysql neumí moc dobře zkombinovat indexy pro podmínku OR na různé sloupce...
active=1 OR instock=1 OR inotherstock=1

Pokud tato podmínka je velmi častá, zauvažoval bych o porušení normálních forem a udělal si pomocný sloupec, který se bude na základě těchto tří sloupců vypočítávat např. triggery. Pak by se hodil jeden index nad třemi sloupci (novypomocnysloupec, category, price)

Dále to not like také rychlosti nepomůže. Pokud je minimum záznamů, které se takto vyfiltrují, tak v mysql je možné dát tuto podmínku do having, které se bude dělat asi až po srovnání. Ale to má vlastně smysl jen při dotazu, kde by byl i nějaký limit. Bez limitu by tato podmínka mohla ovlivňovat také ten nový pomocný sloupec, čímž by se podmínka vyhodla a vzniklo něco jako

SELECT object.id,
       object.name,
       object.url,
       object.sb
FROM   objects
WHERE  novypomocnysloupec = 1
       AND category IN ( 3, 1502, 631, 1444, 1119, 34, 1902, 231,
                         1424, 119, 223, 152, 1611, 144, 111 )
       AND object.price > 10000
ORDER  BY stock DESC,
          date DESC

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0