sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur kan jag infoga vanliga data i en tillfällig tabell från olika scheman?

Först kan du skapa en VIEW för att tillhandahålla denna funktionalitet:

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;

Du kan fråga den här vyn som vilken annan tabell som helst:

SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
  • source är nödvändigt om order_nr är inte unik. Hur skulle du annars garantera unika ordernummer över olika källor?

  • En timestamp without time zone är en tvetydig i ett globalt sammanhang. Det är bara bra i samband med sin tidszon. Om du blandar timestamp och timestamptz måste du placera timestamp vid en viss tidszon med AT TIME ZONE bygga för att få detta att fungera. För mer förklaring läs det här relaterade svaret .

    Jag använder UTC som tidszon, du kanske vill ange en annan. En enkel cast "OrderDate"::timestamptz skulle anta din nuvarande tidszon. AT TIME ZONE tillämpas på en timestamp resulterar i timestamptz . Det var därför jag inte lade till ytterligare en skådespelare.

  • Medan du kan , Jag rekommenderar att du inte använder kamel-case-identifierare i PostgreSQL någonsin . Undviker många typer av möjlig förvirring. Notera de gemener (utan de nu onödiga citattecken) som jag angav.

  • Använd inte varchar(25) som typ för order_nr . Använd bara text utan godtycklig längdmodifierare om det måste vara en sträng. Om alla ordernummer uteslutande består av siffror, integer eller bigint skulle vara snabbare.

Prestanda

Ett sätt att göra detta snabbt skulle vara att materialisera utsikten. Dvs skriv in resultatet i en (tillfällig) tabell:

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

Du behöver ett index. I mitt exempel tillhandahåller primärnyckelbegränsningen indexet automatiskt.

Om dina bord är stora, se till att du har tillräckligt med tillfälliga buffertar att hantera detta i RAM före du skapar temptabellen. Annars kommer det faktiskt att sakta ner dig.

SET temp_buffers = 1000MB;

Måste vara det första anropet till tillfälliga objekt i din session. Sätt inte det högt globalt, bara för din session. En temporär tabell tas bort automatiskt i slutet av din session i alla fall.

För att få en uppskattning av hur mycket RAM-minne du behöver, skapa tabellen en gång och mät:

SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));

Mer om objektstorlekar under denna relaterade fråga på dba.SE .

All overhead betalar sig bara om du måste behandla ett antal frågor inom en session. För andra användningsfall finns det andra lösningar. Om du känner till källtabellen vid tidpunkten för frågan, skulle det vara mycket snabbare att rikta din fråga till källtabellen istället. Om du inte gör det skulle jag ifrågasätta det unika med din order_nr en gång till. Om det faktiskt är garanterat unikt kan du släppa kolumnen source Jag presenterade.

För bara en eller några få frågor kan det vara snabbare att använda vyn istället för den materialiserade vyn.

Jag skulle också överväga en plpgsql-funktion som frågar den ena tabellen efter den andra tills posten hittas. Kan vara billigare för ett par frågor, med tanke på omkostnader. Index för varje tabell som behövs såklart.

Dessutom, om du håller dig till text eller varchar för din order_nr , överväg COLLATE "C" för det.



  1. mysql_num_rows() förväntar sig att parameter 1 är resurs, boolean ges i C:\wamp\www

  2. MySQL-python-installationen misslyckades med utgångsstatus 1120

  3. Fråga prestanda skillnad pl/sql för all infogning och vanlig SQL-infogning

  4. Finns det något sätt att inaktivera uppdateringar/borttagningar men ändå tillåta triggers att utföra dem?