← Zpět na Blog
·8 min čtení·

Pět vzorů SQL, které nahrazují Python smyčku – a proč vyhrávají

Nejdražší Python, které recenzuji, je pro objednávku v objednávkách po SELECT *. Poslední řádek na skupinu, měsíc po měsíci, filtrované počty a upserts jsou dotazy. Jak je píšu v Postgresu místo stahování tabulky.

SQLPostgreSQLPythonVýkonInženýrství
Najme si mě na Upwork

Nejdražší Python, který recenzuji, není netypizovaný handler FastAPI. Je to pořadí pro v objednávkách, které existuje, protože nikdo nenapsal funkci okna. Smyčka vypadá poctivě. Je to také tím, jak se ze zprávy, která trvala čtyři sekundy, stane čtyřicet a v pondělí po dobrém víkendu s prodejem vyprší časový limit.

Již jsem psal, jak vybírám typ databáze. Toto je další vrstva: SQL, které ve skutečnosti píšu, když je produktová otázka „poslední objednávka na zákazníka“, „tržby za tento měsíc versus minulý“ nebo „vložte tuto rezervaci, pokud není obsazeno“. Postgres na ně může odpovědět během jedné zpáteční cesty. Python může také – po stažení tabulky. Doprovodný kus je, jak by měl tento dotaz opustit Python, aniž by se hromada vtahovala zpět.

1. Smyčka, která stahuje tabulku

Typický skript: VYBERTE * Z objednávek, poté seskupte do diktátu a poté vyberte nejnovější created_at podle customer_id. Na 800 řádcích je to v pořádku. Na 800 000 je to lístek na podporu. Databáze k tomu již má index, řazení a paměť. Zaplatil jsi za to. Použití Python jako druhého dotazovacího nástroje je způsob, jak se náklady projeví v latenci, nikoli na faktuře, kterou jste plánovali.

  • Pokud je výsledek menší než zdroj a pravidlo má název – poslední, součet, pořadí, existuje – jedná se o dotaz.
  • Pokud je pravidlem obchodní esej – refundace s lidskou výjimkou, odstavec zásad – může zůstat v Python.

2. Poslední řádek na skupinu – DISTINCT ON a ROW_NUMBER

Aktuální předplatné na pracovní prostor. Nejnovější stav faktury na objednávku. Řidič, který naposledy zapípal. Toto je první smyčka, kterou smažu. V Postgresu píšu DISTINCT ON (workspace_id) a ORDER BY workspace_id, created_at DESC. Přenosný bratranec je ROW_NUMBER() OVER (PARTITION BY workspace_id ORDER BY created_at DESC), pak ponechte rn = 1.

DISTINCT ON je kratší a používám ho, když vlastním Postgres. ROW_NUMBER je to, co píšu, když stejný dotaz musí přežít přesun, nebo když potřebuji hodnost 1 a 2 – předchozí plán, runner-up. Nenačítat každé předplatné a snižovat o Python. Dostanete špatné vazby a načtete sloupce, které nikdy nevykreslíte.

3. Průběžné součty a „od minulého měsíce“ – SUM OVER a LAG

Měsíc po měsíci není spojení tabulky se sebou samým uvnitř smyčky. LAG(revenue) OVER (PARTITION BY workspace_id ORDER BY month) umístí minulý měsíc na stejný řádek. SUM(částka) OVER (PARTITION BY customer_id ORDER BY created_at) je průběžný zůstatek. Funkce okna zachovávají zrnitost řádku a stále vidí okolí. GROUP BY se zhroutí. Smyčka Python přebuduje toto sousedství v diktátu a zapomene na časová pásma.

Pokud potřebujete řádek podrobností i součet skupiny, SUM(částka) NAD (PARTITION BY order_id) překoná druhý dotaz a překoná N+1 z ORM. To je celý trik: zachovejte zrno, které budete renderovat, vypočítejte okolí v enginu.

4. Podmíněné počty – FILTROVAT místo if

COUNT(*) FILTER (WHERE status = zaplaceno) vedle COUNT(*) FILTER (WHERE status = refundováno) je jeden sken. Verze Python je jeden průchod se dvěma počítadly – ​​dokud někdo nepřidá třetí stav ve druhé smyčce, nebo se export rozroste a vy skenujete dvakrát. FILTER je čitelný. CASE uvnitř SUM funguje na motorech, které nikdy neměly FILTR. V Postgresu preferuji FILTER, protože záměr sedí na stránce: tento počet má predikát.

5. Upsert místo select-then-insert

Závod: přečtěte si „je tento e-mail zdarma“ a poté vložte. Dvě karty, dva pracovníci, jedno jedinečné omezení, které objevíte ve výrobě. INSERT ... ON CONFLICT (e-mail) DO UPDATE – nebo DO NOTHING – je transakce, kterou databáze již ví, jak spustit. Stejná rodina: UPDATE ... WHERE verze = $verze pro optimistický zámek. Pokud zaškrtnete a zapíšete v Python, zapisujete horší databázi.

  • Rezervační sloty, klíče idempotence, „vytvoření zákazníka, pokud chybí“ – to jsou upserts, ne if-bloky.
  • Součástí produktu je unikátní index. Bez toho je ON CONFLICT divadlem.

6. Jak zkontroluji Nevymyslel jsem pomalejší dotaz

VYSVĚTLIT (ANALÝZA, VYROVNÁVAT) na pomalé cestě. Pokud vidíte sekvenční skenování na tabulce, která vyrostla, potřebujete index, který odpovídá oddílu a pořadí – (id_pracovního prostoru, vytvořeno_při DESC) pro DISTINCT ON. Funkce okna není zdarma. Stále je to levnější než poslat hromadu do aplikace. Pokud plán seřadí dva miliony řádků pro řídicí panel, který zobrazuje dvacet, přidejte ohraničení datem. SQL, který nahrazuje smyčku, může být stále špatnou smyčkou uvnitř enginu.

Závěr: pojmenujte sadu výsledků, napište dotaz

Python je dobré místo pro HTTP, zásady a větu, kterou ukazujete uživateli. Je to špatné místo pro znovuobjevení GROUP BY. Naučte se pět tvarů – poslední na skupinu, zpoždění, průběžný součet, filtrované agregáty, upsert – a většina „chytrých“ skriptů, které kontrolujem, se stane pohledem nebo jediným dotazem ve funkci úložiště. Dalším článkem je Python, který tuto práci odmítá vrátit zpět.

Pronájem na 1 kliknutí

Najměte si mě jako svého vývojáře jedním kliknutím. Začněte bezpečnou Upwork smlouvu na vytvoření vysoce konverzních webových řešení pro vaši firmu.

Najměte si mě na Upwork

Jste připraveni diskutovat o svém projektu?

Jsem senior webový inženýr se specializací na React a Next.js – dostupné pro projekty na volné noze po celém světě.

Umístění

Kyjev, Ukrajina