/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
Stored procedure, Ikke altid godt at bruge~
Fra : Jimmy


Dato : 10-09-03 13:11

Hey

Spørgsmål 1:
Har et sqlkald som ser således ud:
streng = "and (felt2 = 'vaerdi1' or felt2 = 'vaerdi2') 'Ved godt at jeg
måske burde have haft lavet en "in" her, men kan vi lige se bort fra det :)
"Select count(*) from tabel where felt1 = '" & var1 & "' " & streng

Har prøvet at lave det om til en stored procedure som bliver kaldt på denne
her måde:
CREATE PROCEDURE [OWNER].[proc_name]
@var1 nvarchar(20),
@streng nvarchar(255)
AS
Select count(*) from tabel where felt1 = @var1 + @streng
GO

EXEC proc_name '3001', [ and (felt2 = 'vaerdi1' or felt2 = 'vaerdi2')]

Kører fint bortset fra at den første SQL returnerer 1 og den anden SQL
returnerer 0 (altså den med stored procedures)

Hvad gør jeg galt?
....og er der overhovedet nogen ide i at lave dette om til en stored
procedure når jeg alligevel danner det meste af where klusulen i en
variabel?

Spørgsmål2:
Har lavet lavet en insert om til en stored procedure på samme måde. Dette
virker til gengæld upåklageligt.
Insert into tabel (felt1, felt2, felt3, felt4, felt5) values ('" & var1 &
"', '" & var2 & "', '" & var3 & "', '" & var4 & "', '" & var5 & "')

Er lavet om til:
CREATE PROCEDURE [OWNER].[proc_name2]
@var1 nvarchar(20),
@var2 nvarchar(255),
@var3 nvarchar(255),
@var4 nvarchar(10),
@var5 nvarchar(20)
AS
Insert into tabel (felt1, felt2, felt3, felt4, felt5) values (@var1, @var2,
@var3, @var4, @var5)
GO

exec proc_name2 'testtekst1', 'testtekst2', 'testtekst3', 'testtekst4',
'testtekst5'

Jeg har lavet nogle målinger for hvor hurtigt mit program kørte, men de kan
selvfølgelig være påvirket af anden aktivitet på SQL Serveren. Med den
manuelle SQL lavede jeg 3 test:
1. 23 sek
2. 22 sek
3. 23 sek.

Med den stored procedure:
1. 51 sek.
2. 24 sek.
3. 17 sek.
4. 17 sek.

Min umiddelbare vurdering er at det går meget hurtigere med insert som en
stored procedure. Kan jeg tage fejl her?

Da jeg kom selecten på (fra spørgsmål 1) som en stored procedure (den kørte
den jo trods alt selvom den returnerer noget forkert), så tiderne således ud
her:
1. 35 sek.
2. 18 sek.
3. 29 sek.
4. 18 sek.

Ikke en gang kom jeg ned under 17, og derfor konkluderer jeg at SQLen fra
spørgsmål 1, vil være en dårlig ide at køre som en stored procedure.

Kan jeg ikke have ret i mine betragtninger?
Hvorfor?

Håber der er nogen der kan hjælpe? :)


--


Jimmy
P.S. Hvis nogen undrer sig over hvorfor jeg har sådan nogle høje tider kan
jeg lige fortælle at programmet bliver brugt til at læse linier fra en
tekstfil, hvor der som regel ligger flere tusinder af linier. Hver linie
skal behandles ved at jeg checker for om den allerede findes i systemet.
Hvis den ikke gør bliver den lagt ind.



 
 
Peter Lykkegaard (10-09-2003)
Kommentar
Fra : Peter Lykkegaard


Dato : 10-09-03 15:07


"Jimmy" <pleasereplyingroup@hotmail.com> wrote in a message

[klip ]

Lige et spørgsmål før vi går igang med den udvidet ledvogter ting
Hvilket programmeringsprog bruger
Muligvis den her kan være til inspiration
http://www.asp-faq.dk/article/?id=102

mvh/Peter Lykkegaard



Poul-Erik Andreasen (10-09-2003)
Kommentar
Fra : Poul-Erik Andreasen


Dato : 10-09-03 15:52

On Wed, 10 Sep 2003 14:11:01 +0200
"Jimmy" <pleasereplyingroup@hotmail.com> wrote:

> Hey
>
> Spørgsmål 1:
> Har et sqlkald som ser således ud:
> streng = "and (felt2 = 'vaerdi1' or felt2 = 'vaerdi2') 'Ved godt at jeg
> måske burde have haft lavet en "in" her, men kan vi lige se bort fra det :)
> "Select count(*) from tabel where felt1 = '" & var1 & "' " & streng

Den expantion du foretager her er noget som sker i dit programmeringsprog
ikke i SQL, når SQl bliver kaldt er selectstatemeted blevet expanderet.
Det kan ud ikke trække med ind i en stored procedure.

> Har prøvet at lave det om til en stored procedure som bliver kaldt på denne
> her måde:
> CREATE PROCEDURE [OWNER].[proc_name]
> @var1 nvarchar(20),
> @streng nvarchar(255)
> AS
> Select count(*) from tabel where felt1 = @var1 + @streng
> GO
>
> EXEC proc_name '3001', [ and (felt2 = 'vaerdi1' or felt2 = 'vaerdi2')]
>
> Kører fint bortset fra at den første SQL returnerer 1 og den anden SQL
> returnerer 0 (altså den med stored procedures)
> Hvad gør jeg galt?

Det er AND tegnet der er problemet del vil ikke blive opfattet som et KEYWORD
men som noget der skal søges efter i feltet.

> ...og er der overhovedet nogen ide i at lave dette om til en stored
> procedure når jeg alligevel danner det meste af where klusulen i en
> variabel?

Aner det ikke

> Spørgsmål2:
> Har lavet lavet en insert om til en stored procedure på samme måde. Dette
> virker til gengæld upåklageligt.
> Insert into tabel (felt1, felt2, felt3, felt4, felt5) values ('" & var1 &
> "', '" & var2 & "', '" & var3 & "', '" & var4 & "', '" & var5 & "')
>
> Er lavet om til:
> CREATE PROCEDURE [OWNER].[proc_name2]
> @var1 nvarchar(20),
> @var2 nvarchar(255),
> @var3 nvarchar(255),
> @var4 nvarchar(10),
> @var5 nvarchar(20)
> AS
> Insert into tabel (felt1, felt2, felt3, felt4, felt5) values (@var1, @var2,
> @var3, @var4, @var5)
> GO
>
> exec proc_name2 'testtekst1', 'testtekst2', 'testtekst3', 'testtekst4',
> 'testtekst5'
>
> Jeg har lavet nogle målinger for hvor hurtigt mit program kørte, men de kan
> selvfølgelig være påvirket af anden aktivitet på SQL Serveren. Med den
> manuelle SQL lavede jeg 3 test:
> 1. 23 sek
> 2. 22 sek
> 3. 23 sek.
>
> Med den stored procedure:
> 1. 51 sek.
> 2. 24 sek.
> 3. 17 sek.
> 4. 17 sek.
>
> Min umiddelbare vurdering er at det går meget hurtigere med insert som en
> stored procedure. Kan jeg tage fejl her?
>
> Da jeg kom selecten på (fra spørgsmål 1) som en stored procedure (den kørte
> den jo trods alt selvom den returnerer noget forkert), så tiderne således ud
> her:
> 1. 35 sek.
> 2. 18 sek.
> 3. 29 sek.
> 4. 18 sek.
>
> Ikke en gang kom jeg ned under 17, og derfor konkluderer jeg at SQLen fra
> spørgsmål 1, vil være en dårlig ide at køre som en stored procedure.

Du kan ikke lave noget konklutioner af af noget art på din procedure
før den fungere som den skal.

> Kan jeg ikke have ret i mine betragtninger?
> Hvorfor?
>
> Håber der er nogen der kan hjælpe? :)
>
>
> --
>
>
> Jimmy
> P.S. Hvis nogen undrer sig over hvorfor jeg har sådan nogle høje tider kan
> jeg lige fortælle at programmet bliver brugt til at læse linier fra en
> tekstfil, hvor der som regel ligger flere tusinder af linier. Hver linie
> skal behandles ved at jeg checker for om den allerede findes i systemet.
> Hvis den ikke gør bliver den lagt ind.

Så er det vigtigste at du sørger for at lave index på det felt som indholder
linjer. Hvad skal du i øvrigt bruge en AND til i den anledning?

Hvad med at læse hver ny teksfil ind i en temporær tabel og så lave en
union med et destinct select på den temporære tabel

Poul-Erik



Jimmy (12-09-2003)
Kommentar
Fra : Jimmy


Dato : 12-09-03 11:26

> "Poul-Erik Andreasen" <poulerik@pea.dk> skrev i en meddelelse
news:20030910165229.59d9229a.poulerik@pea.dk...
> On Wed, 10 Sep 2003 14:11:01 +0200

>> P.S. Hvis nogen undrer sig over hvorfor jeg har sådan nogle høje tider
kan
>> jeg lige fortælle at programmet bliver brugt til at læse linier fra en
>> tekstfil, hvor der som regel ligger flere tusinder af linier. Hver linie
>> skal behandles ved at jeg checker for om den allerede findes i systemet.
>> Hvis den ikke gør bliver den lagt ind.

> Så er det vigtigste at du sørger for at lave index på det felt som
indholder
> linjer. Hvad skal du i øvrigt bruge en AND til i den anledning?

Sagen er den at tekstfilerne ikke er ens for brugerne af systemet. På den
måde kan flere forskellige brugere ligge flere forskellige linier ind. Jeg
bruger and til at sørge for at der bliver selected og inserted for den
rigtige bruger.

> Hvad med at læse hver ny teksfil ind i en temporær tabel og så lave en
> union med et destinct select på den temporære tabel

Det kunne jeg selvfølgelig gøre. På den måde ville jeg spare selecten hver
gang jeg skulle køre dataene ind. Men den temporære tabel ville jo ende med
at blive på mange millioner rows. Så det vil vel gå ud over ventetiden når
man selecter på tabellen senere hen. Det er vigtigere at det går hurtigt når
man i programmerne selecter data. Det er selvfølgelig også vigtigt at det
går hurtigt når de ligger tekstfilen ind, men det må ikke være på bekostning
af at det så går langsommere i de programmer brugerne bruger når de skal
læse dataene i systemet.

Jeg ved dog ikke om du mener at jeg kunne bruge den temporære tabel til
først at ligge alt ind, og så bruge en union med distinct select på den
temporære tabel til at ligge data ind på den rigtige tabel til sidst. I så
falde ville jeg skifte eksempelvis:
3000 selects
+3000 inserts
ud med
3000 inserts i den temporære tabel
+1 insert i den oprindelige tabel med en sub select der henter data fra den
temporære tabel. Gad vide om det vil være hurtigere???
Meget interessant ide. Det kunne være jeg lige skulle prøve at lege lidt med
den...



Kristian Damm Jensen (11-09-2003)
Kommentar
Fra : Kristian Damm Jensen


Dato : 11-09-03 07:28

"Jimmy" <pleasereplyingroup@hotmail.com> skrev i en meddelelse
news:3f5f1313$0$13173$edfadb0f@dread15.news.tele.dk...
> Hey
>
> Spørgsmål 1:
> Har et sqlkald som ser således ud:
> streng = "and (felt2 = 'vaerdi1' or felt2 = 'vaerdi2') 'Ved godt at jeg
> måske burde have haft lavet en "in" her, men kan vi lige se bort fra det
:)
> "Select count(*) from tabel where felt1 = '" & var1 & "' " & streng
>
> Har prøvet at lave det om til en stored procedure som bliver kaldt på
denne
> her måde:
> CREATE PROCEDURE [OWNER].[proc_name]
> @var1 nvarchar(20),
> @streng nvarchar(255)
> AS
> Select count(*) from tabel where felt1 = @var1 + @streng
> GO
>
> EXEC proc_name '3001', [ and (felt2 = 'vaerdi1' or felt2 = 'vaerdi2')]

Lad mig se:

Når proc_name bliver kald får @var1 værdien "3001" og @streng værdien "and
(felt2 = 'vaerdi1' or felt2 = 'vaerdi2')"

Den select der udføres bliver dermed:

Select count(*) from tabel where felt1 = "3001" + "and (felt2 = 'vaerdi1' or
felt2 = 'vaerdi2')"

Under de omstændigheder kan det vist ikke overraske, at du ikke får det
forventede resultat

> Kører fint bortset fra at den første SQL returnerer 1 og den anden SQL
> returnerer 0 (altså den med stored procedures)
>
> Hvad gør jeg galt?
> ...og er der overhovedet nogen ide i at lave dette om til en stored
> procedure når jeg alligevel danner det meste af where klusulen i en
> variabel?

Det kommer an på, hvad du ønsker i det generelle tilfælde. Hvis du kan leve
med en procedure, der ser således ud:

CREATE PROCEDURE [OWNER].[proc_name]
@var1 nvarchar(20),
@vaerdi1 nvarchar(255),
@vaerdi2 nvarchar(255)
AS
Select count(*) from tabel
where felt1 = @var1
and (felt2 = @vaerdi1 or felt2 = @vaerdi2)

altså, hvis du altid har netop den struktur på din select, så er det en fin
idé. Ellers havner du i at skulle lave dynamisk sql inde i proceduren. Det
kan godt lade sig gøre (i al fald i de varianter, jeg kender til), men hvis
der ikke er overbevisende argumenter for det, kan du lige så godt føre det i
værtssproget.

> Spørgsmål2:
> Har lavet lavet en insert om til en stored procedure på samme måde. Dette
> virker til gengæld upåklageligt.
> Insert into tabel (felt1, felt2, felt3, felt4, felt5) values ('" & var1 &
> "', '" & var2 & "', '" & var3 & "', '" & var4 & "', '" & var5 & "')
>
> Er lavet om til:
> CREATE PROCEDURE [OWNER].[proc_name2]
> @var1 nvarchar(20),
> @var2 nvarchar(255),
> @var3 nvarchar(255),
> @var4 nvarchar(10),
> @var5 nvarchar(20)
> AS
> Insert into tabel (felt1, felt2, felt3, felt4, felt5) values (@var1,
@var2,
> @var3, @var4, @var5)
> GO
>
> exec proc_name2 'testtekst1', 'testtekst2', 'testtekst3', 'testtekst4',
> 'testtekst5'
>
> Jeg har lavet nogle målinger for hvor hurtigt mit program kørte, men de
kan
> selvfølgelig være påvirket af anden aktivitet på SQL Serveren. Med den
> manuelle SQL lavede jeg 3 test:
> 1. 23 sek
> 2. 22 sek
> 3. 23 sek.
>
> Med den stored procedure:
> 1. 51 sek.
> 2. 24 sek.
> 3. 17 sek.
> 4. 17 sek.
>
> Min umiddelbare vurdering er at det går meget hurtigere med insert som en
> stored procedure. Kan jeg tage fejl her?

Et meget typisk mønster. En af fordelene ved en stored procedure er at
eksekveringsplanen laves én gang for alle, fremfor hver gang du udfører din
sql (med mindre du netop benytter dynamisk sql, eller på anden måde
gennemtvinger en genoversættelse hver gang). Derfor tager proceduren længere
tid at udføre 1. gang men er hurtigere ved de efterfølgende kørsler.

> Da jeg kom selecten på (fra spørgsmål 1) som en stored procedure (den
kørte
> den jo trods alt selvom den returnerer noget forkert), så tiderne således
ud
> her:
> 1. 35 sek.
> 2. 18 sek.
> 3. 29 sek.
> 4. 18 sek.
>
> Ikke en gang kom jeg ned under 17, og derfor konkluderer jeg at SQLen fra
> spørgsmål 1, vil være en dårlig ide at køre som en stored procedure.

Da de to ikke laver det samme stykke arbejde, er en sammenligning
meningsløs.

> P.S. Hvis nogen undrer sig over hvorfor jeg har sådan nogle høje tider kan
> jeg lige fortælle at programmet bliver brugt til at læse linier fra en
> tekstfil, hvor der som regel ligger flere tusinder af linier. Hver linie
> skal behandles ved at jeg checker for om den allerede findes i systemet.
> Hvis den ikke gør bliver den lagt ind.

Index, index, index. Der findes i øvrigt i mange systemer faciliteter, der
gør netop det arbejde for dig. I Sybase kan man fx oprette et clustered
index med ignore_dup_row. Herefter vil basen blot ignorere alle forsøg på at
indsætte dubletter!

Vh
Kristian



Jimmy (12-09-2003)
Kommentar
Fra : Jimmy


Dato : 12-09-03 11:30

"Kristian Damm Jensen" <REdammMOVE@ofir.dk> skrev i en meddelelse
news:bjp4s9$kq7lt$1@ID-146708.news.uni-berlin.de...
> "Jimmy" <pleasereplyingroup@hotmail.com> skrev i en meddelelse
> news:3f5f1313$0$13173$edfadb0f@dread15.news.tele.dk...
> > ...og er der overhovedet nogen ide i at lave dette om til en stored
> > procedure når jeg alligevel danner det meste af where klusulen i en
> > variabel?
>
> Det kommer an på, hvad du ønsker i det generelle tilfælde. Hvis du kan
leve
> med en procedure, der ser således ud:
>
> CREATE PROCEDURE [OWNER].[proc_name]
> @var1 nvarchar(20),
> @vaerdi1 nvarchar(255),
> @vaerdi2 nvarchar(255)
> AS
> Select count(*) from tabel
> where felt1 = @var1
> and (felt2 = @vaerdi1 or felt2 = @vaerdi2)
>
> altså, hvis du altid har netop den struktur på din select, så er det en
fin
> idé. Ellers havner du i at skulle lave dynamisk sql inde i proceduren. Det
> kan godt lade sig gøre (i al fald i de varianter, jeg kender til), men
hvis
> der ikke er overbevisende argumenter for det, kan du lige så godt føre det
i
> værtssproget.

Ok, men jeg er faktisk sikker på at jeg godt kan lave det om til den version
du skriver. Tror også lige jeg vil lave en in i stedet for.

> > P.S. Hvis nogen undrer sig over hvorfor jeg har sådan nogle høje tider
kan
> > jeg lige fortælle at programmet bliver brugt til at læse linier fra en
> > tekstfil, hvor der som regel ligger flere tusinder af linier. Hver linie
> > skal behandles ved at jeg checker for om den allerede findes i systemet.
> > Hvis den ikke gør bliver den lagt ind.
>
> Index, index, index. Der findes i øvrigt i mange systemer faciliteter, der
> gør netop det arbejde for dig. I Sybase kan man fx oprette et clustered
> index med ignore_dup_row. Herefter vil basen blot ignorere alle forsøg på
at
> indsætte dubletter!

Ok, det er meget interessant!
Kan man gøre det med MS SQL Server?


Jimmy



Peter Lykkegaard (11-09-2003)
Kommentar
Fra : Peter Lykkegaard


Dato : 11-09-03 07:57


"Jimmy" <pleasereplyingroup@hotmail.com> wrote in message
news:3f5f1313$0$13173$edfadb0f@dread15.news.tele.dk...

> P.S. Hvis nogen undrer sig over hvorfor jeg har sådan nogle høje tider kan
> jeg lige fortælle at programmet bliver brugt til at læse linier fra en
> tekstfil, hvor der som regel ligger flere tusinder af linier. Hver linie
> skal behandles ved at jeg checker for om den allerede findes i systemet.
> Hvis den ikke gør bliver den lagt ind.
>
Kik på SQL-DMO og bulk inserts, jeg har classes der "replikerer" data fra
3die parts systemer
Data bliver gemt i tekst filer (csv) og indlæst via bulk insert

mvh/Peter Lykkegaard



Jimmy (12-09-2003)
Kommentar
Fra : Jimmy


Dato : 12-09-03 11:36

"Peter Lykkegaard" <polonline@hot.mail.com> skrev i en meddelelse
news:31V7b.13$n71.9@news.get2net.dk...
>
> "Jimmy" <pleasereplyingroup@hotmail.com> wrote in message
> news:3f5f1313$0$13173$edfadb0f@dread15.news.tele.dk...
>
> > P.S. Hvis nogen undrer sig over hvorfor jeg har sådan nogle høje tider
kan
> > jeg lige fortælle at programmet bliver brugt til at læse linier fra en
> > tekstfil, hvor der som regel ligger flere tusinder af linier. Hver linie
> > skal behandles ved at jeg checker for om den allerede findes i systemet.
> > Hvis den ikke gør bliver den lagt ind.
> >
> Kik på SQL-DMO og bulk inserts, jeg har classes der "replikerer" data fra
> 3die parts systemer
> Data bliver gemt i tekst filer (csv) og indlæst via bulk insert

Ja, det er ligesom om jo mere jeg ved om det, bliver jeg klar over hvor
meget jeg egentlig ikke ved. Havde aldrig hørt om bulk inserts før nu. Har
fundet en del om det på microsofts hjemmeside, og tror faktisk at det er
noget jeg kan bruge.

Dette er taget fra microsofts hjemmeside:
BULK INSERT Northwind.dbo.[Order Details]
FROM 'f:\orders\lineitem.tbl'
WITH
(
FIELDTERMINATOR = '|',
ROWTERMINATOR = '|\n'
)

Det fede ved det her, som jeg kan forstå, er at man kan læse filen direkte
ind i tabellen, med en SQL. Samtidigt betyder det at alt log arbejdet
(næsten) som SQL Serveren udfører bliver slået fra, så det går noget
stærkere.

Er det ikke korrekt forstået?

2 spørgsmål dukker lige op.
Hvis jeg nu har 4 felter i min tekstfil, men 5 felter i min tabel, har jeg
så muligheden for selv at kunne fylde en værdi i det femte felt?

Kristian snakkede om ignore_dup_row i SyBase, hvis den også findes i MS SQL
Server og jeg kan kombinere den med dette, så er min lykke (i hvert fald
vedr. dette, hehe...) helt sikkert gjort. Ved du om det kan lade sig gøre?

Hvad er SQL-DMO?


Jimmy :)



Peter Lykkegaard (12-09-2003)
Kommentar
Fra : Peter Lykkegaard


Dato : 12-09-03 12:33


"Jimmy" <pleasereplyingroup@hotmail.com> wrote in a message
>
> Det fede ved det her, som jeg kan forstå, er at man kan læse filen direkte
> ind i tabellen, med en SQL. Samtidigt betyder det at alt log arbejdet
> (næsten) som SQL Serveren udfører bliver slået fra, så det går noget
> stærkere.

Loggen slås fra på godt og ondt
>
> Er det ikke korrekt forstået?
>
> 2 spørgsmål dukker lige op.
> Hvis jeg nu har 4 felter i min tekstfil, men 5 felter i min tabel, har jeg
> så muligheden for selv at kunne fylde en værdi i det femte felt?
>
Kombiner evt med Poul-Eriks forslag

> Kristian snakkede om ignore_dup_row i SyBase, hvis den også findes i MS
SQL
> Server og jeg kan kombinere den med dette, så er min lykke (i hvert fald
> vedr. dette, hehe...) helt sikkert gjort. Ved du om det kan lade sig gøre?
>
Kombiner evt med Poul-Eriks forslag
Noget select distinct skal fedtes ind

> Hvad er SQL-DMO?
>
Det er MSSQL's object hierarki som DAO er for access (ca)
Prøv Google

mvh/Peter Lykkegaard



Poul-Erik Andreasen (12-09-2003)
Kommentar
Fra : Poul-Erik Andreasen


Dato : 12-09-03 12:05

On Fri, 12 Sep 2003 12:26:10 +0200
"Jimmy" <pleasereplyingroup@hotmail.com> wrote:

> > "Poul-Erik Andreasen" <poulerik@pea.dk> skrev i en meddelelse
> news:20030910165229.59d9229a.poulerik@pea.dk...
> > On Wed, 10 Sep 2003 14:11:01 +0200
>
> >> P.S. Hvis nogen undrer sig over hvorfor jeg har sådan nogle høje tider
> kan
> >> jeg lige fortælle at programmet bliver brugt til at læse linier fra en
> >> tekstfil, hvor der som regel ligger flere tusinder af linier. Hver linie
> >> skal behandles ved at jeg checker for om den allerede findes i systemet.
> >> Hvis den ikke gør bliver den lagt ind.
>
> > Så er det vigtigste at du sørger for at lave index på det felt som
> indholder
> > linjer. Hvad skal du i øvrigt bruge en AND til i den anledning?
>
> Sagen er den at tekstfilerne ikke er ens for brugerne af systemet. På den
> måde kan flere forskellige brugere ligge flere forskellige linier ind. Jeg
> bruger and til at sørge for at der bliver selected og inserted for den
> rigtige bruger.
>
> > Hvad med at læse hver ny teksfil ind i en temporær tabel og så lave en
> > union med et destinct select på den temporære tabel
>
> Det kunne jeg selvfølgelig gøre. På den måde ville jeg spare selecten hver
> gang jeg skulle køre dataene ind. Men den temporære tabel ville jo ende med
> at blive på mange millioner rows. Så det vil vel gå ud over ventetiden når
> man selecter på tabellen senere hen. Det er vigtigere at det går hurtigt når
> man i programmerne selecter data. Det er selvfølgelig også vigtigt at det
> går hurtigt når de ligger tekstfilen ind, men det må ikke være på bekostning
> af at det så går langsommere i de programmer brugerne bruger når de skal
> læse dataene i systemet.
>
> Jeg ved dog ikke om du mener at jeg kunne bruge den temporære tabel til
> først at ligge alt ind, og så bruge en union med distinct select på den
> temporære tabel til at ligge data ind på den rigtige tabel til sidst. I så
> falde ville jeg skifte eksempelvis:
> 3000 selects
> +3000 inserts
> ud med
> 3000 inserts i den temporære tabel
> +1 insert i den oprindelige tabel med en sub select der henter data fra den
> temporære tabel. Gad vide om det vil være hurtigere???
> Meget interessant ide. Det kunne være jeg lige skulle prøve at lege lidt med
> den...

efter nærmer eftertanke er det ikke en UNION der er bedst det er en EXCEPT
så kan du nemlig gøre følgende

du starter med at indlæse den nye file i en tmp tabel
vi kalder for tmpnew derefter skulle følgende kunne klare det

INSERT into bigtabel (felt1, ....)

SELECT DESTINCT * FROM tmpnem EXCEPT SELECT * FROM bigtabel

Så vil den tage dem som findes 1 gang i tmpnew og som ikke findes
i bigtabel og lægge dem ind i bigtabel

Den kan du sikkert med fordel lægge ind i en stroed procedure
med den tmpnew som den eneste variable. Så sparer du optimeringen.

Men hvorfor kan du ikke bare lave en UNIQE CONSTRAINT på den store tabel
og læse alle filerne ind fra en ende af? så skulle den da meget gerne afvise dem der findes i forvejen.













Poul-Erik Andreasen (16-09-2003)
Kommentar
Fra : Poul-Erik Andreasen


Dato : 16-09-03 12:05

On Tue, 16 Sep 2003 09:16:31 +0200
"Jimmy" <pleasereplyingroup@hotmail.com> wrote:

> > > > Hvad med at læse hver ny teksfil ind i en temporær tabel og så lave en
> > > > union med et destinct select på den temporære tabel
> > >
> > > Det kunne jeg selvfølgelig gøre. På den måde ville jeg spare selecten
> hver
> > > gang jeg skulle køre dataene ind. Men den temporære tabel ville jo ende
> med
> > > at blive på mange millioner rows. Så det vil vel gå ud over ventetiden
> når
> > > man selecter på tabellen senere hen. Det er vigtigere at det går hurtigt
> når
> > > man i programmerne selecter data. Det er selvfølgelig også vigtigt at
> det
> > > går hurtigt når de ligger tekstfilen ind, men det må ikke være på
> bekostning
> > > af at det så går langsommere i de programmer brugerne bruger når de skal
> > > læse dataene i systemet.
> > >
> > > Jeg ved dog ikke om du mener at jeg kunne bruge den temporære tabel til
> > > først at ligge alt ind, og så bruge en union med distinct select på den
> > > temporære tabel til at ligge data ind på den rigtige tabel til sidst. I
> så
> > > falde ville jeg skifte eksempelvis:
> > > 3000 selects
> > > +3000 inserts
> > > ud med
> > > 3000 inserts i den temporære tabel
> > > +1 insert i den oprindelige tabel med en sub select der henter data fra
> den
> > > temporære tabel. Gad vide om det vil være hurtigere???
> > > Meget interessant ide. Det kunne være jeg lige skulle prøve at lege lidt
> med
> > > den...
>
> > efter nærmer eftertanke er det ikke en UNION der er bedst det er en
> EXCEPT
> så kan du nemlig gøre følgende
>
> > du starter med at indlæse den nye file i en tmp tabel
> > vi kalder for tmpnew derefter skulle følgende kunne klare det
>
> > INSERT into bigtabel (felt1, ....)
>
> > SELECT DESTINCT * FROM tmpnem EXCEPT SELECT * FROM bigtabel
>
> > Så vil den tage dem som findes 1 gang i tmpnew og som ikke findes
> > i bigtabel og lægge dem ind i bigtabel
>
> > Den kan du sikkert med fordel lægge ind i en stroed procedure
> > med den tmpnew som den eneste variable. Så sparer du optimeringen.
>
> > Men hvorfor kan du ikke bare lave en UNIQE CONSTRAINT på den store tabel
> > og læse alle filerne ind fra en ende af? så skulle den da meget gerne
> afvise dem der findes i forvejen.
>
> I Enterprise Manager kan man sætte den som unique constrain eller unique
> index under index/keys. Det er kun hvis jeg sætter den som unique index at
> jeg kan sætte hak i "ignore duplicate key". Hvis jeg herefter kører en
> insert kan jeg se at den ligger rækkerne ind som den skal, men den kommer
> alligevel lige og fortæller mig at der er duplicate keys i en
> fejlmeddelelse. Det er godt nok kun testet ved at køre inserts i Enterprise
> Manager. Gør jeg noget forkert?

Jeg ikke Windows-bruger så de nærmere detaljer kan jeg ikke hjælpe med, men det
er klart at den vil komme med en fejlmeddelelse når du laver inserts som er
dubletter. Men hvis den i øvrigt sætter de nye rækker ind som de skal, så kan du
vel være ligeglad.

Du kan vel altid selv sørge for at inorere den fejlmedelelse fra det program der
laver dine inserts, eller evt lave en parsning så du det kun er fejlmedelelser
af den type der bliver inoreret, mens fejlmeddelelser der tyder på at der er
noget galt bliver udlæst.

Spørgsmålet er vil i sidste instans være om det er hurtigere, end at
lave en temporær tabel og en except med destinct.

--
Poul-Erik Andreasen

http://www.linux-service.dk
http://www.pea.dk

Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408521
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste