PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak mogę wstawić wspólne dane do tabeli tymczasowej z różnych schematów?

Najpierw możesz utworzyć VIEW aby zapewnić tę funkcjonalność:

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;

Możesz sprawdzić ten widok jak każdą inną tabelę:

SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
  • source jest konieczne, jeśli order_nr nie jest wyjątkowy. W jaki inny sposób gwarantowałbyś unikalne numery zamówień z różnych źródeł?

  • timestamp without time zone jest niejednoznaczny w kontekście globalnym. To jest dobre tylko w połączeniu z jego strefą czasową. Jeśli mieszasz timestamp i timestamptz , musisz umieścić timestamp w określonej strefie czasowej z AT TIME ZONE konstruktu, aby to zadziałało. Aby uzyskać więcej wyjaśnień, przeczytaj powiązaną odpowiedź .

    Używam UTC jako strefy czasowej, możesz podać inną. Prosty rzut "OrderDate"::timestamptz przyjmie Twoją obecną strefę czasową. AT TIME ZONE zastosowano do timestamp wyniki w timestamptz . Dlatego nie dodałem kolejnej obsady.

  • Póki możesz , radzę nie używać identyfikatorów wielbłądów w PostgreSQL ever . Unika wielu możliwych pomyłek. Zwróć uwagę na identyfikatory małych liter (bez niepotrzebnych teraz podwójnych cudzysłowów), które podałem.

  • Nie używaj varchar(25) jako typ dla order_nr . Po prostu użyj text bez modyfikatora dowolnej długości, jeśli ma to być ciąg. Jeśli wszystkie numery zamówień składają się wyłącznie z cyfr, integer lub bigint byłoby szybsze.

Wydajność

Jednym ze sposobów, aby to przyspieszyć, byłoby zmaterializowanie widoku. Np. zapisz wynik do (tymczasowej) tabeli:

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);

potrzebujesz indeks. W moim przykładzie ograniczenie klucza podstawowego zapewnia indeks automatycznie.

Jeśli Twoje tabele są duże, upewnij się, że masz wystarczająco dużo buforów tymczasowych obsłużyć to w pamięci RAM przed tworzysz tabelę tymczasową. W przeciwnym razie faktycznie Cię spowolni.

SET temp_buffers = 1000MB;

Musi być pierwszym wywołaniem obiektów tymczasowych w Twojej sesji. Nie ustawiaj go na wysokim poziomie globalnie, tylko na swoją sesję. Tabela tymczasowa i tak jest automatycznie usuwana pod koniec sesji.

Aby uzyskać szacunkową ilość potrzebnej pamięci RAM, utwórz tabelę raz i zmierz:

SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));

Więcej informacji o rozmiarach obiektów znajdziesz w tym pytanie na dba.SE .

Wszystkie koszty ogólne opłacają się tylko wtedy, gdy musisz przetworzyć kilka zapytań w ramach jednej sesji. Dla innych przypadków użycia istnieją inne rozwiązania. Jeśli znasz tabelę źródłową w momencie zapytania, znacznie szybciej byłoby skierować zapytanie do tabeli źródłowej. Jeśli nie, kwestionowałbym wyjątkowość twojego order_nr jeszcze raz. Jeśli w rzeczywistości gwarantuje się, że jest unikalny, możesz usunąć kolumnę source przedstawiłem.

W przypadku tylko jednego lub kilku zapytań szybsze może być użycie widoku zamiast widoku zmaterializowanego.

Rozważyłbym również funkcję plpgsql który wykonuje zapytania jedną tabelę po drugiej, aż do znalezienia rekordu. Może być tańsze w przypadku kilku zapytań, biorąc pod uwagę obciążenie. Oczywiście indeksy dla każdej tabeli.

Ponadto, jeśli trzymasz się text lub varchar dla Twojego order_nr , rozważ COLLATE "C" za to.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy istnieje odpowiednik Postgresql KAŻDEJ funkcji agregującej w innych RDBMS?

  2. postgres:uaktualnić użytkownika do superużytkownika?

  3. nie rozumiem json_agg w tym kontekście

  4. 100% wykorzystanie procesora spowodowane przez nieznane zapytanie postgres

  5. JDBC Gotowy parametr instrukcji wewnątrz json