sql >> Databáze >  >> RDS >> PostgreSQL

Jak mohu vložit běžná data do dočasné tabulky z různých schémat?

Nejprve můžete vytvořit VIEW poskytovat tuto funkci:

CREATE VIEW orders AS
SELECT '1'::int            AS source -- or any other tag to identify source
      ,"OrderNumber"::text AS order_nr
      ,"InvoiceNumber"     AS tansaction_id -- no cast .. is int already
      ,"OrderDate" AT TIME ZONE 'UTC' AS purchase_date -- !! see explanation
FROM   tbl_newegg

UNION  ALL  -- not UNION!
SELECT 2
       "amazonOrderId"
      ,"merchant-order-id"
      ,"purchase-date"
FROM   tbl_amazon;

Tento pohled můžete dotazovat jako jakoukoli jinou tabulku:

SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
  • source je nutné, pokud order_nr není unikátní. Jak jinak byste zaručili jedinečná objednací čísla z různých zdrojů?

  • timestamp without time zone je v globálním kontextu nejednoznačný. Je to dobré jen ve spojení s jeho časovým pásmem. Pokud smícháte timestamp a timestamptz , musíte umístit timestamp v určitém časovém pásmu pomocí AT TIME ZONE vytvořit, aby to fungovalo. Pro další vysvětlení si přečtěte tuto související odpověď .

    Jako časové pásmo používám UTC, možná budete chtít zadat jiné. Jednoduché obsazení "OrderDate"::timestamptz předpokládá vaše aktuální časové pásmo. AT TIME ZONE použito na timestamp výsledkem je timestamptz . Proto jsem nepřidal další obsazení.

  • Zatímco můžete , doporučuji nepoužívat identifikátory velbloudího případu v PostgreSQL nikdy . Vyhnete se mnoha možným záměnám. Všimněte si malých identifikátorů (bez nyní zbytečných dvojitých uvozovek), které jsem dodal.

  • Nepoužívejte varchar(25) jako typ pro order_nr . Stačí použít text bez libovolného modifikátoru délky, pokud to má být řetězec. Pokud se všechna objednací čísla skládají výhradně z číslic, integer nebo bigint bylo by to rychlejší.

Výkon

Jedním ze způsobů, jak to udělat rychle, by bylo zhmotnění pohledu. Výsledek zapište do (dočasné) tabulky:

CREATE TEMP TABLE tmp_orders AS
SELECT * FROM orders;

ANALYZE tmp_orders; -- temp tables are not auto-analyzed!

ALTER TABLE tmp_orders
ADD constraint orders_pk PRIMARY KEY (order_nr, source);

potřebujete index. V mém příkladu omezení primárního klíče poskytuje index automaticky.

Pokud jsou vaše stoly velké, ujistěte se, že máte dostatek dočasných vyrovnávacích pamětí abyste to zvládli v RAM před vytvoříte dočasnou tabulku. Jinak vás to ve skutečnosti zpomalí.

SET temp_buffers = 1000MB;

Musí to být první volání dočasných objektů ve vaší relaci. Nenastavujte to globálně vysoko, jen pro vaši relaci. Dočasná tabulka se na konci relace stejně automaticky zruší.

Chcete-li získat odhad, kolik paměti RAM potřebujete, vytvořte jednou tabulku a změřte:

SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));

Více o velikostech objektů v této související otázce na dba.SE .

Veškerá režie se platí pouze v případě, že musíte zpracovat více dotazů v rámci jedné relace. Pro jiné případy použití existují jiná řešení. Pokud znáte zdrojovou tabulku v době dotazu, bylo by mnohem rychlejší přesměrovat dotaz do zdrojové tabulky. Pokud ne, zpochybnil bych jedinečnost vašeho order_nr ještě jednou. Pokud je ve skutečnosti zaručeno, že je jedinečný, můžete sloupec source vypustit Představil jsem.

Pouze pro jeden nebo několik dotazů může být rychlejší použít zobrazení místo materializovaného zobrazení.

Také bych zvážil funkci plpgsql který se dotazuje jednu tabulku za druhou, dokud není záznam nalezen. Mohlo by to být levnější na pár dotazů, s ohledem na režii. Indexy pro každou tabulku jsou samozřejmě potřeba.

Také pokud se budete držet text nebo varchar pro váš order_nr , zvažte COLLATE "C" za to.



  1. psycopg2 ve skutečnosti nevkládá data

  2. Výběr MySQL na základě rozsahu denních časových razítek

  3. Nelze zvýšit max_open_files pro Mysql max-connections v Ubuntu 15

  4. SQL dotaz pro nalezení řádku s určitým počtem asociací