24. oktober 2006 - 08:52Der er
5 kommentarer og 1 løsning
SQL Søgning i et view, Interbase 7.5
Hej
Jeg har et problem med at når jeg laver en søgning i et view, tager der utroligt lang tid.
Databasen er på ca. 1 GB, med div. tabeller med op til 2-300.000 records.
Databasen indeholder en tabel (Test), som indeholder div GUIDs som linker til andre tabeller. f.eks GuidTest, GuidVehicle og GuidCustomer
Hvor GuidVehicle, GuidCustomer findes i hhv. tabellen Vehicle og Customer. Jeg har et view(View_Combi), hvor en tabel(test) indeholder Joins til f.eks. Vehicle og Customer tabellerne.
Hvis Jeg f.eks. skriver : select * From View_combi where RegNo = "AB12345" ; så tager søgningen ca 12 sek. Jeg har index på RegNo og GuidVehicle
jeg har også prøvet: SELECT GuidTest FROM Test WHERE GUIDVEHICLE IN (SELECT GUIDVEHICLE FROM VEHICLE WHERE RegNo = "AB12345"); Her er tiden på ca 6 sek.
Jeg har kørt SQL kaldet i SQL Manager 2005 for Interbase og Firebird, som under preformace analyse skriver at alle opslag i test tabellen er Non-Indexed reads, men der er indexer på alle felter i den tabel.
GuidVehicle er primær nøgle i Tabellen Vehicle GuidCustomer er primær nøgle i tabellen Customer I tabellen Test er feleterne GuidVehicle og GuidCustomer indekseret, dog uden det hjælper på hastigheden. Jeg får den samme hastighed, hvis jeg fjerner indexerne på de to felter
Når nu du skriver GUID's; er det så tekststrenge du søger på? Det må være tungt. Har du mulighed for at lave en opstilling hvor nøglerne er heltal (oprette tabellerne men hvor referencen til Customer og Vehicle er integer.
Ja, det er textstrenges. Hvis jeg selv laver opslaget i Vehicle tabellen først, og så bruger DE GuidVehicle som det opslag retunerer, til at slå op i Viewet, kan jeg finde et resultat på f.eks. 10 mS. Det dur bare ikke med mange resultater
Var SQLStr : String ; SearchList : TStringList ; i : integer ;
SQLStr := 'Select GuidVehicle from Vehicle Where RegNo = ''AB12356'' Rows 100'; Sql.Clear; Sql.Add(SQLStr) ;
Open ; First ; While not eof do begin SearchList.Add(FieldByName('GuidVehicle').AsString ); Next ; end ; end ;
if SearchList.Count > 0 then begin with Query1 do begin if Active then Close; Sql.Clear; SQLStr := 'Select * from View_Combi ' ;
if SearchList.Count > 0 then SQLStr := SQLStr + ' Where ' ; for i := 0 to SearchList.Count - 1 do begin SQLStr := SQLStr + ' ( GuidVehicle = :pGuidVehicle'+IntToStr(i) + ' )' ; if i < SearchList.Count - 1 then SQLStr := SQLStr + ' OR ' ; end ; end ; end ;
Sql.Add(SQLStr) ; for i := 0 to SearchList.Count - 1 do ParamByName('pGUIDVehicle' + IntToStr (i) ).AsString := SearchList[i] );
Hvad med at banke resultatet over i en temp-tabel hvor der så er et begrænset antal records og lave dine joins med den - og så lade det køre i en stored-procedure somd it view kalder?
delete from temptabel insert into temptabel select guidvehicle from vehicle where regno = @regno
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.