Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Michael K.
Člen
Avatar
Michael K.:6.5.2019 13:00

Ahoj,

chci se zeptat - pokud použiji INNER JOIN v MSSQL dotazu a podmínku where ..

Jak to funguje z hlediska posloupnosti, co se děje v pozadí v databázi ? Řeším optimalizaci selectů.

Dejme tomu, že mám tyto tabulky (úplně zjednodušeně):
tabulka uzivatele

ID Jmeno Bydliste Oddeleni
1 Michael Třinec IT
2 Tomáš Ostrava IT
3 Roman Ostrava HR
4 Lukáš Střítež IT

tabulka faktury

ID_faktury ID_uzivatele Castka
FA1111 1 1000
FA2222 3 1599
FA3333 1 2400
FA4444 3 7249
FA5555 4 500
FA6666 2 399
FA7777 1 470
FA8888 1 1200

Pokud použiju dotaz:

SELECT * FROM faktury f
INNER JOIN uzivatele u on f.ID_Uzivatele=u.ID
WHERE u.Oddeleni= 'IT'

Jak to probíhá v pozadí ? Nejprve se udělá INNER JOIN a až poté se použije WHERE ? tzn. v pozadí by bylo 8 řádků a až poté se odfiltruje řádek s FA2222 a FA4444 ? Nebo se nejprve odfiltruje z tabulky uzivatele **Roman ? A až poté se provede **INNER JOIN ? Nevím, zda jsem dobře vysvětlil mou myšlenku, ale snad ano :)

Jde mi o to, aby zbytečně neporovnával Romana s každou fakturou i když ho nakonec podmínkou WHERE vyřadím.

Potřeboval bych zkrátka něco v tomto smyslu:

SELECT * FROM faktury f
INNER JOIN uzivatele u WHERE u.Oddeleni='IT' on f.ID_Uzivatele=u.ID
WHERE u.Bydliste = 'IT'

Děkuji :)

Zkusil jsem: U optimalizace jsem také přišel na to, že pokud selectuji pouze sloupce, které potřebuji a nepoužiji z lenosti klasiku **SELECT * **, tak je výsledek z databáze obdržen rychleji.

Chci docílit: Optimalizace SELECTu.

 
Odpovědět
6.5.2019 13:00
Avatar
Petr Langer
Člen
Avatar
Odpovídá na Michael K.
Petr Langer:6.5.2019 13:28

Nedávno jsem řešil něco podobného. Ten tvůj druhý dotaz bych udělal spíš takhle

SELECT * FROM faktury f
INNER JOIN uzivatele u ON f.ID_Uzivatele=u.ID AND u.Oddeleni='IT'
WHERE u.Bydliste = 'IT'

Ta druhá podmínka by taky možná šla vložit přímo do JOINU, to už si musíš vyzkoušet sám

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
6.5.2019 13:28
Avatar
Matěj K
Člen
Avatar
Matěj K:6.5.2019 13:31

Ahoj,

orientace zpracování dotazů funguje v tomto pořadí:
FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY.

V tvém případě bych určitě postupoval takto:

SELECT *
FROM faktury AS f
JOIN uzivatele AS u ON f.ID_Uzivatele = u.ID
AND u.Bydliste = 'IT'

Tím se vyhneš celé klauzuli WHERE a rovnou si vyfiltruješ daný JOIN. Ze svých zkušeností a z kurzů vím, že je tato možnost nejpřesnější.

Matěj

 
Nahoru Odpovědět
6.5.2019 13:31
Avatar
Matěj K
Člen
Avatar
Matěj K:6.5.2019 13:31

Případně si můžeš přidat i více podmínek viz:
AND u.Bydliste = 'IT' AND u.Oddeleni = 'IT'

 
Nahoru Odpovědět
6.5.2019 13:31
Avatar
Michael K.
Člen
Avatar
Michael K.:6.5.2019 14:11

Mám tam překlep, mělo to být WHERE u.Bydliste = 'Ostrava' jako další podmínka.

Každopádně teď zkouším a zkouším :) Nevěděl jsem, že za ON podmínka může být AND.

Tahám data ze SAP databáze, kde jsou statisíce řádků a selecty potřebuji co nejrychleji.

Jen bych se chtěl zeptat jen tak offtopic - dá se v MSSQL management studiu zjistit v záložce Results ke které tabulce daný sloupec náleží ?

Nebo zda jde zapnou jakýsi "rozdělovač", který mi ukáže ve výsledcích, kde už začíná další tabulka.

Děkuji

 
Nahoru Odpovědět
6.5.2019 14:11
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:6.5.2019 14:41

Ja bych sloupce pojmenoval takto, podle vyznamu

uzivatele: id_uzivatel, Jmeno, Bydliste, Oddeleni, ...
faktury: id_faktura, Castka, ...
uzivatel_faktury: id_uzivatel, id_faktura

Joiny obvykle nepouzival, jenom LEFT JOIN, ale nemel bys do selectu vypsat jmena sloupcu? Pokud se bude kryt nazev sloupce z tab a s jinym v b, tak SELECT * bude pindat error.
Nevim, jestli bych u joinu resil AND u.Bydliste = 'IT', spis bych to dal pak do where. Ale to bych musel testnout, co je rychlejsi. Teoreticky WHERE, protoze se nemusi kontrolovat join s podminkou.
A potom bych teda asi pouzil treti tabulku pro propojeni uzivatel faktura. Ale to je na uvazeni. Zhlediska rychlosti by nemel byt rozdil.

SELECT uf.id_faktura, u.jmeno, f.castka
FROM uzivatel_faktury uf
    LEFT JOIN uzivatele u ON u.id_uzivatel = uf.id_uzivatel
 -- nemusis premyslet nad nazvy sloupcu, protoze mas v obou tabulkach stejne pojmenovane sloupce
    LEFT JOIN faktury f ON f.id_faktura = uf.id_faktura
WHERE u.Oddeleni= 'IT'

Navic bych na Oddeleni udelal extra tabulku a filtroval to pomoci id, ne (u.Oddeleni= 'IT'), o.Oddeleni= 1.

Editováno 6.5.2019 14:43
 
Nahoru Odpovědět
6.5.2019 14:41
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Michael K.
Peter Mlich:6.5.2019 14:55

S temi sloupci a tabulkami moc nerozumim. Ale, neznam ten program...
Select vybere data z tabulek a vrati tabulku. Ktery sloupec tam chces , v jakem poradi si definujes za SELECT slovem. Pokud tam mas *, tak to bere vsechny sloupce. Poradi tabulek bude, jake mas definovane za FROM, ne? * pouzivaji jen ti nejvetsi luzri :) Kteri si radi pridelavaji pozdeji problemy.

 
Nahoru Odpovědět
6.5.2019 14:55
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:6.5.2019 14:57

Mimochodem...
Co kdyby se uzivatel prestehoval? Ve starych fakturach budes mit novou adresu? To je preci spatne, ne?
A co kdyby zmenil jmeno, slecna se provda. Ve starych fakturach bude figurovat nove jmeno?
A co kdyz meni pohlavi?

 
Nahoru Odpovědět
6.5.2019 14:57
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Peter Mlich
Peter Mlich:6.5.2019 15:02

K tem tabulkam, znovu jsem si to precetl... V mem pripade to funguje takto:

FROM uzivatel_faktury uf
    LEFT JOIN uzivatele u ON u.id_uzivatel = uf.id_uzivatel
 -- nemusis premyslet nad nazvy sloupcu, protoze mas v obou tabulkach stejne pojmenovane sloupce
    LEFT JOIN faktury f ON f.id_faktura = uf.id_faktura

Otevri tabulku uzivatel_faktury. Ke kazdemu radu pridej data z uzivatele a z faktury (resp, on tam prida jen ukazatel/pointer databaze.tabul­ka.radek).
Ziska jednu obri tabulku. Poradi radku bude podle tabulky uzivatel_faktury.
A na zaver posklada data do tabulky podle toho, co mas v SELECT. Jestli tam mas GROUP BY, WHERE a tak, tak to filtruje.

Jo, jestli chces mit na konci nejake poradi, zkus pouzit ORDER BY (mysql), v msql nevim. Tam se ale tusim pise jinak jen LIMIT.

Editováno 6.5.2019 15:04
 
Nahoru Odpovědět
6.5.2019 15:02
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.