LEFT JOIN s GROUP anebo SUBSELECT ve sloupci rubrika: Databáze: SQL

12 rmaslo
položil/-a 27.10.2017
 
upravil/-a 27.10.2017

Zdravím,
takový nijak důležitý, odpočinkový, teoretický dotaz na víkend :-).

Je obecný, ale popíšu jej na příkladu: Mějme tabulku "faktury" a "faktury_rozpis". Tabulka faktury má id (je to PK), firma_id, var_sym, atd... prostě hlavička faktury a pro tento příklad nemá sloupec cena (i když samozřejmě vím, že se tam většinou dává a počítá se průběžně), který budeme v tomto příkladě pro výpis faktur vysčítávat z tabulky "faktury_rozpis".
Ta tabulka "faktury_rozpis" má samozřejmě sloupec faktura_id pomocí, kterého se položky faktury vážou na danou hlavičku faktury a pak tam jsou nějaká běžné sloupce jako cena, pocet, atd... Sloupec faktura_id má samozřejmě index.

Přijde Vám jako lepší "LEFT JOIN":

SELECT firma_id, var_sym, ... SUM(pocet*cena) AS celkem FROM faktury LEFT JOIN faktury_rozpis ON faktury_rozpis.faktura_id = faktury.id GROUP BY faktury.id LIMIT 25

nebo "SUBSELECT":

SELECT firma_id, var_sym, ... (SELECT SUM(pocet*cena) FROM faktury_rozpis WHERE faktury_rozpis.faktura_id = zr_faktury.id) AS celkem FROM faktury LIMIT 25

? Konkrétně je to MySQL a když neuměla subselecty tak jsme si zvykl na ten LEFT JOIN přístup, ale teď se mi zdá ten přístup se subselectem takový čištější. Jde mi o to jestli tam někdo nevidíte nějakou zradu třeba z hlediska výkonu a tak nějak vůbec ... co byste použili ... a proč?

odkaz
9 LeonardoCA
odpověděl/-a 28.10.2017
 
upravil/-a 28.10.2017

Aby ti bylo jasne co pouzit a proc, mas nejlepsi si to prakticky vyzkouset:

  1. pustit ty dotazy s EXPLAIN

  2. pustit ty dotazy nad dostatecne velkou sadou dat
    (Vygeneruj si nejake random testovaci data. Par milionu az stovek milionu zaznamu, by mohlo stacit.)

Spoiler alert: zatimco s pouzitim JOINU nebudes mit sebemensi problemy, pri volani subselectu se ti muze stat, ze kompletne shodis system.

Duvod je, ze subselect vytvari temporary table, ktera se pri vetsim mnozstvi dat (ne)sikovne napsanem selectu nevleze do ramky a dost mozna ani na harddrive. V lepsim pripade se dotaz trvajici par milisekund muze protahnout na minuty, hodiny, ci dny

Komentáře

  • harrison314 : S MySQL sa mi subselektom podarilo niekolkokrat zabit instanciu, a to tam boli tabulky len o okolo desat tisi zaznamami. Ale zalezi od databazy, napriklad MS SQL nema so subselektami najmensi problem. 28.10.2017
  • podhy : Jen doplním že od osmičkový verze MySQL by s tím už problémy neměly být. 28.10.2017

Pro zobrazení všech 4 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.