03.12.2021 15:31
1
SELECT c.category as cat, p.*, DATE_FORMAT(`added`, '%e.%m.%y' ) AS datum, d.distributor as dist, p.base_price * p.quantity
as total_price FROM products p left join categories c on c.id=p.category left join distributor d on d.id=p.distributor
where p.name like '%muti%' or unique_key like '%muti%' order by p.id DESC;

SELECT categories.category as cat, products.*, DATE_FORMAT(`added`, '%e.%m.%y' ) AS datum, distributor.distributor as dist, products.base_price * products.quantity
as total_price FROM products, categories, distributor where categories.id=products.category and distributor.id=products.distributor and
products.name like '%muti%' or unique_key like '%muti%' order by products.id DESC; 

Vrací stejné výsledky a bez joinů je dotaz rychlejší.  Kdy se používá join? A v tomto případě jak tento dotaz vylepšit? Použít první dotaz nebo druhý? Jde o tabulku s pár tis řádků max.
03.12.2021 16:09
2
dej si na těch dotazech explain, i ten druhý používá join, jenom se jedná o inner join.

Bez hodnosti tabulek a jejich schémat ti nedokážu říct přesně, kde je problém.

V prvním případě se např. podmínka products.name like '%muti%' or unique_key like '%muti%' vyhodnocuje na všech záznamech, v druhém případě jenom na těch záznamech, které se spojily, tj. které jsou ve výsledku, pokud třeba ty kategorie jsou víceúrovňové či mají nějakou n:m vazbu, může to takhle ušetřit obrovské spousty porovnávání, oboustranný like je v mysql asi ten nejdražší výraz.
03.12.2021 16:14
3
Pro zajímavost, ten první můžeš přepsat jako:

Kód:
SELECT c.category as cat, p.*, DATE_FORMAT(`added`, '%e.%m.%y' ) AS datum, d.distributor as dist, p.base_price * p.quantity
as total_price
FROM products p
join categories c on c.id=p.category
join distributor d on d.id=p.distributor
where p.name like '%muti%' or unique_key like '%muti%' order by p.id DESC;
a měl by být stejně rychlý jako ten druhý.
03.12.2021 16:31
4
Původně odeslal TomášX
Pro zajímavost, ten první můžeš přepsat jako:

Kód:
SELECT c.category as cat, p.*, DATE_FORMAT(`added`, '%e.%m.%y' ) AS datum, d.distributor as dist, p.base_price * p.quantity
as total_price
FROM products p
join categories c on c.id=p.category
join distributor d on d.id=p.distributor
where p.name like '%muti%' or unique_key like '%muti%' order by p.id DESC;
a měl by být stejně rychlý jako ten druhý.
to je stejný jako ten první akorát bez "LEFT"?

---------- Příspěvek doplněn 03.12.2021 v 22:33 ----------

Původně odeslal TomášX
dej si na těch dotazech explain, i ten druhý používá join, jenom se jedná o inner join.

Bez hodnosti tabulek a jejich schémat ti nedokážu říct přesně, kde je problém.

V prvním případě se např. podmínka products.name like '%muti%' or unique_key like '%muti%' vyhodnocuje na všech záznamech, v druhém případě jenom na těch záznamech, které se spojily, tj. které jsou ve výsledku, pokud třeba ty kategorie jsou víceúrovňové či mají nějakou n:m vazbu, může to takhle ušetřit obrovské spousty porovnávání, oboustranný like je v mysql asi ten nejdražší výraz.
ano, ale nechápu, proč je join v tomto případě pomalejší ale.
0,0064 vs 0,0054
03.12.2021 17:17
5
rozdíl mezi 5,5 a 6,5 ms může být dán i zatížením serveru, cachováním dat či jinými příčinami, je to příliš malé číslo.

Left join tahá více dat a musí pracovat s nulovými sloupci, inner join (či jen join) to dělat nemusí.

Dej sem výstup explain (před samorný sql na začátek napíšeš explain) a řeknu ti k tomu více, takhle mohu jen střílet.
03.12.2021 18:13
6
Původně odeslal TomášX
rozdíl mezi 5,5 a 6,5 ms může být dán i zatížením serveru, cachováním dat či jinými příčinami, je to příliš malé číslo.

Left join tahá více dat a musí pracovat s nulovými sloupci, inner join (či jen join) to dělat nemusí.

Dej sem výstup explain (před samorný sql na začátek napíšeš explain) a řeknu ti k tomu více, takhle mohu jen střílet.
prvni: 
druhy:
07.12.2021 09:47
7
V explainech jde vidět, že ten první (left join) dotaz nejprve načte 160 produktů (očividně všechny), k nim připojí kategorie a nakonec distributory, všechny připojení jsou přes indexy. U prvního dotazu je tedy nutné projít všech 160 produktů a na nich provést drahé hledání přes oboustranný like.

V druhém (explicitní inner join) se nejprve načte 6 řádků z kategorií, k tomu se připojí 10 řádků z distribotorů a nakonec se pro připojená data spustí porovnání přes like, opět se provádí like na všech 160 produktech.

V dotazech tedy není velký rozdíl a fungují obdobně. Rozdíly se začnou ukazovat až tam přidáš nějaký další filtr třeba na kategorie, pak podle rozložení kategorií a počtu produktů mohou být časy výraznější. Dívej se hlavně na počet položek na řádku s tabulkou products, kde má "possible_keys" hodnotu NULL, tady probíhá ta nejdražší operace v celém dotazu a tvým cílem je minimalizovat počet řádků, na kterých se hledá.