sql >> Database teknologi >  >> RDS >> Oracle

INDSÆT med 10 millioner forespørgsler under 10 minutter i Oracle?

Jeg ved, at andre har nævnt dette, og du ønsker ikke at høre det, men brug SQL*Loader eller eksterne tabeller. Min gennemsnitlige indlæsningstid for tabeller med omtrent samme bredde er 12,57 sekunder for lidt over 10m rækker. Disse hjælpeprogrammer er eksplicit designet til at indlæse data i databasen hurtigt og er ret gode til det. Dette kan medføre nogle ekstra tidsstraffe afhængigt af formatet på din inputfil, men der er en del muligheder, og jeg har sjældent været nødt til at ændre filer før indlæsning.

Hvis du ikke er villig til at gøre dette, behøver du ikke opgradere din hardware endnu; du skal fjerne enhver mulig hindring for at indlæse dette hurtigt. For at opregne dem skal du fjerne:

  1. Indekset
  2. Udløseren
  3. Rækkefølgen
  4. Partitionen

Med alle disse tvinger du databasen til at udføre mere arbejde, og fordi du gør dette transaktionsmæssigt, bruger du ikke databasen til sit fulde potentiale.

Indlæs dataene i en separat tabel, sig ABC_LOAD . Når dataene er blevet fuldstændig indlæst, skal du udføre en enkelt INSERT sætning i ABC.

insert into abc
select abc_seq.nextval, a.*
  from abc_load a

Når du gør dette (og selvom du ikke gør det), skal du sikre dig, at sekvenscachens størrelse er korrekt; for at citere:

Når et program får adgang til en sekvens i sekvenscachen, læses disse sekvensnumre hurtigt. Men hvis et program får adgang til en sekvens, der ikke er i cachen, skal sekvensen læses fra disk til cachen, før sekvensnumrene bruges.

Hvis dine applikationer bruger mange sekvenser samtidigt, er din sekvenscache muligvis ikke stor nok til at indeholde alle sekvenserne. I dette tilfælde kan adgang til sekvensnumre ofte kræve disklæsning. For hurtig adgang til alle sekvenser skal du sørge for, at din cache har nok poster til at indeholde alle de sekvenser, der bruges samtidigt af dine applikationer.

Dette betyder, at hvis du har 10 tråde, der samtidig skriver 500 poster, hver ved hjælp af denne sekvens, har du brug for en cachestørrelse på 5.000. ALTER SEQUENCE-dokumentet angiver, hvordan dette ændres:

alter sequence abc_seq cache 5000

Hvis du følger mit forslag, vil jeg øge cachestørrelsen til noget omkring 10,5 m.

Se nærmere på at bruge APPEND-tip (se også Oracle Base); dette instruerer Oracle om at bruge en direkte-sti-indsættelse, som tilføjer data direkte til slutningen af ​​tabellen i stedet for at lede efter plads til at sætte dem. Du vil ikke være i stand til at bruge dette, hvis din tabel har indekser, men du kan bruge det i ABC_LOAD

insert /*+ append */ into ABC (SSM_ID, invocation_id , calc_id, ... )
select 'c','b',NULL, 'test', 123 , 'N', 'asdf' from dual
union all select 'a','b',NULL, 'test', 123 , 'N', 'asdf' from dual
union all select 'b','b',NULL, 'test', 123 , 'N', 'asdf' from dual
union all select 'c','g',NULL, 'test', 123 , 'N', 'asdf' from dual

Hvis du bruger APPEND tippet; Jeg ville tilføje TRUNCATE ABC_LOAD efter du har indsat i ABC ellers vil denne tabel vokse i det uendelige. Dette burde være sikkert, da du til den tid er færdig med at bruge tabellen.

Du nævner ikke, hvilken version eller udgave eller Oracle du bruger. Der er en række ekstra små tricks, du kan bruge:

  • Oracle 12c

    Denne version understøtter identitetskolonner; du kunne slippe af med sekvensen helt.

    CREATE TABLE ABC(
       seq_no         NUMBER GENERATED AS IDENTITY (increment by 5000)
    
  • Oracle 11g r2

    Hvis du holder aftrækkeren; du kan tildele sekvensværdien direkte.

    :new.seq_no := ABC_seq.nextval;
    
  • Oracle Enterprise Edition

    Hvis du bruger Oracle Enterprise, kan du fremskynde INSERT fra ABC_LOAD ved at bruge det PARALLELLE tip:

    insert /*+ parallel */ into abc
    select abc_seq.nextval, a.*
      from abc_load a
    

    Dette kan forårsage sine egne problemer (for mange parallelle processer osv.), så test. Det måske hjælp til de mindre batch-indsatser, men det er mindre sandsynligt, da du vil miste tid på at beregne, hvilken tråd der skal behandle hvad.

tl;dr

Brug de hjælpeprogrammer, der følger med databasen.

Hvis du ikke kan bruge dem, skal du slippe af med alt, der kan gøre indsatsen langsommere og gøre det i bulk, for det er det, databasen er god til.



  1. Topsvar på 5 brændende spørgsmål om COALESCE-funktion i SQL Server

  2. Lagret procedure med valgfri WHERE-parametre

  3. SQL mellem operatør

  4. EXECUTE-tilladelsen blev nægtet på objektet 'xxxxxxx', databasen 'zzzzzzz', skemaet 'dbo'