it-swarm-eu.dev

Je lepší rozdělit velký dotaz do několika menších dotazů?

Existují situace, které vyžadují, aby byl opravdu velký dotaz spojující několik tabulek spolu s příkazy sub-select, aby bylo dosaženo požadovaných výsledků.

Moje otázka zní, měli bychom zvážit použití několika menších dotazů a přivést logické operace do aplikační vrstvy dotazováním na DB ve více než jednom volání, nebo je lepší nechat je všechny najednou?
Zvažte například následující dotaz:

SELECT *
FROM   `users`
WHERE  `user_id` IN (SELECT f2.`friend_user_id`
                     FROM   `friends` AS f1
                            INNER JOIN `friends` AS f2
                              ON f1.`friend_user_id` = f2.`user_id`
                     WHERE  f2.`is_page` = 0
                            AND f1.`user_id` = "%1$d"
                            AND f2.`friend_user_id` != "%1$d"
                            AND f2.`friend_user_id` NOT IN (SELECT `friend_user_id`
                                                            FROM   `friends`
                                                            WHERE  `user_id` = "%1$d"))
       AND `user_id` NOT IN (SELECT `user_id`
                             FROM   `friend_requests`
                             WHERE  `friend_user_id` = "%1$d")
       AND `user_image` IS NOT NULL
ORDER  BY Rand() 
LIMIT %2$d

Jaký je nejlepší způsob, jak toho dosáhnout?

13
Hamed Momeni

Tady nesouhlasím s velkými a komplikovanými dotazy s datagodem. Vidím je pouze jako problémy, pokud jsou zmatené. Pokud jde o výkon, jsou téměř vždy lepší, protože plánovač má mnohem větší svobodu při získávání informací. Velké dotazy však musí být psány s ohledem na údržbu. Obecně jsem zjistil, že jednoduchý, dobře strukturovaný SQL lze snadno ladit, i když jediný dotaz pokračuje pro 200+ řádků. Je to proto, že obvykle máte docela dobrou představu o tom, s jakým problémem se zabýváte, takže v dotazu je jen několik oblastí, které musíte zkontrolovat.

Problémy s údržbou, IME, přicházejí, když se rozpadne struktura SQL. Dlouhé, složité dotazy v dílčím výběru zhoršují čitelnost a odstraňování problémů, stejně jako inline pohledy, a při obou dotazech je třeba se vyhnout. Místo toho použijte ZOBRAZENÍ, pokud je to možné (všimněte si, že jste na MySQL, zobrazení nefungují tak dobře, ale na většině ostatních db to dělají), a použijte běžné výrazy tabulek, kde ti nefungují (MySQL tyto nepodporuje Mimochodem).

Dlouhé složité dotazy fungují velmi dobře, a to jak z důvodu údržby, tak z hlediska výkonu, kdy si necháváte klauzule tam, kde je to jednoduché, a kde uděláte cokoli, co můžete, s připojením namísto podvýberů. Cílem je zajistit, aby „záznamy se nezobrazovaly“, vám poskytne několik velmi konkrétních míst v dotazu ke kontrole (je to upuštěno do spojení nebo odfiltrováno v klauzuli where?) A tým údržby dokáže věci skutečně udržovat.

Pokud jde o škálovatelnost, mějte na paměti, že čím větší flexibilita má projektant, to je také dobrá věc ....

Edit: Vy zmiňujete, že se jedná o MySQL, takže je nepravděpodobné, že by pohledy fungovaly tak dobře, a CTE jsou mimo otázku. Uvedený příklad navíc není příliš dlouhý nebo složitý, takže to není žádný problém.

14
Chris Travers

Jako někdo, kdo musí tyto velké a komplikované dotazy podporovat/čistit, bych řekl, že je mnohem lepší rozdělit je na několik malých snadno srozumitelných kousků. Není to nutně lepší z hlediska výkonu, ale přinášejí SQL lepší šanci přijít s dobrým plánem dotazů.

Usnadněte život lidem, kteří vás sledují, a oni o vás řeknou dobré věci. Usnadněte jim to a budou vás proklínat.

8
datagod

Moje 2 centy na 2 klíčová slova dotaz-výkon a škálovatelnost:

Query-Performance: SQL Server rovnoběžnost již dělá velmi dobrou práci, která rozděluje dotazy do vícevláknových vyhledávání, takže si nejsem jistá, kolik zlepšení výkonu dotazu uvidíte tím, že to provedete pro SQL Server. Budete se muset podívat na plán provedení, abyste zjistili, jak velkou míru rovnoběžnosti získáte, když ji provedete, a porovnejte výsledky oběma způsoby. Pokud nakonec potřebujete použít nápovědu k dotazu, abyste dosáhli stejného nebo lepšího výkonu, pak to IMO nestojí za to, protože nápověda k dotazu nemusí být později optimální.

Škálovatelnost: Čtení dotazů může být jednodušší, jak je uvedeno v datagodu, a jeho rozčlenění na samostatné dotazy má smysl, pokud můžete své nové dotazy použít i v jiných oblastech, ale pokud je nebudete používat. pro další hovory také bude ještě více uložených proců pro správu pro 1 úkol a IMO nepřispěje k škálovatelnosti.

5
Ali Razeghi

Někdy není na výběr, ale rozdělit velký/komplexní dotaz na malé dotazy. Nejlepší způsob, jak zjistit, že by bylo použití příkazu EXPLAIN s příkazem SELECT. Počet tras/skenů, které váš db provede pro načtení vašich dat, je součinem hodnot „řádků“ vrácených dotazem EXPLAIN. V našem případě jsme měli dotaz spojující 10 tabulek. U konkrétního záznamu stopa činila 409 miliónů, které blogovaly naši DB a posunuly naše využití CPU našeho serveru DB o více než 300%. Stejné informace se nám podařilo získat mnohem rychlejším rozdělením dotazů.

Stručně řečeno, v některých případech má rozdělení složitého/velkého dotazu smysl, ale v jiných to může vést k mnoha problémům s výkonem nebo údržbou, a to by mělo být řešeno případ od případu.

2
user140665