19. november 2014 - 13:18Der er
10 kommentarer og 1 løsning
Optimering af sql statment
Jeg har to tables der er helt ens. Den ene hedder contacts og den anden doublets.
Jeg vil gerne i en sql statment søge alle igennem i contacts og se om der er nogle ens. De er ens hvis feltet 'firstName' er det samme. Hvis to eller flere er ens ønsker jeg at den kontakt med 'timeStamp' bliver i contacts og alle de andre bliver flyttet til doublets. Jeg har gjort dette på flere måde men da begge tabeller har rigtigt mange rows skal det optimeres så meget som muligt. Håber der er en som kan hjælpe med dette.
Mit sidste forsøg er dette: INSERT INTO lcm_doublets( SELECT * FROM lcm_contacts WHERE `id` NOT IN ( SELECT `id` FROM ( SELECT * FROM ( SELECT * FROM lcm_contacts ORDER BY `timeStamp` ASC ) t1 GROUP BY `firstName` ) t2 ) ) Dette virker men er alt for langsomt. Opgaven haster så alt hjælp er værdsat!
Problemstillingen er mig desværre ikke helt tydelig. Du siger, tror jeg, at hvis der i contacts tabellen er adskillige rækker med samme firstName, så vil du bevare den række med timeStamp, og de andre rækker skal indsættes i tabellen doublets og slettes i contacts.
Det at du taler om at bevare den kontakt med timeStamp, betyder det, at nogle rækker har feltet timeStamp fyldt ud, hvorimod i andre rækker timeStamp er tomt? Og hvis der for eksempel er fire rækker med firstName 'Christian,' så vil en af rækkerne altid have en værdi i timeStamp og de andre tre rækker altid have en tom timeStamp? Og at de kontakter hvoraf der ingen doublets er altid vil have en værdi i timeStamp? Hvis det er tilfældet, så kan opgaven vel forenkles til at flytte alle rækker med en tom timeStamp til tabellen doublets. Dette er næppe tilfældet, ellers ville du have løst det allerede, men hvordan skal det forstås, at du vil bevare den kontakt med timeStamp?
Men ihvorvel din kode indsætter dubletterne i doublets tabellen, så sletter den vist ikke dubletterne fra contacts tabellen. Hvis det er en engangs opgave at sortere rækkerne i en tabel og du for fremtiden sørger for at holde contacts tabellen ren, så var det måske simplest at splitte contacts tabellen i to, contacts1 og doublets. For eksempel noget i denne henretning (ikke testet), først
INSERT INTO contacts1 (SELECT * FROM contacts ORDER BY timeStamp ASC GROUP BY firstName)
og så
INSERT INTO doublets (SELECT * FROM contacts WHERE id IN (SELECT id FROM contacts1) )
og så slette contacts tabellen og derefter rename contacts1 til contacts.
Det er det svære ikke en engangsopgave. Jeg kan godt oprette en table mere og gøre det på den måde. Men er det den hurtigste måde? Er ikke så stærk i optimering af sql så lidt lost her. :)
Om mit forslag er hurtigere kunne vel komme an på en prøve. Men du siger, at koden i dit oprindelige spørgsmål virker. Gør den mere end den ene opgave, indsætte dubletter i doublets tabellen? Du vil jo også have dubletterne fjernet fra contacts tabellen.
Men hvis du ikke vil have dubletter i contacts tabellen, hvorfor bliver du så ved med at indsætte nye dubletter, således at du skal blive ved med bagefter at sortere dem? Hvor bliver kontakter indsat i contacts tabellen? Hvis du ændrede koden der, således at koden for hver ny kontakt checker, om contacts tabellen allerede har en med det pågældende firstName, og hvis den har, så placer den nye kontact i doublets med det samme. Det ville i min mening være den bedste optimering, at holde orden i stedet for at skulle blive ved med at gøre orden.
Igen tak for du gider hjælpe mig selvom jeg ikke forklare mig så godt.
Som du siger så vil det være mest optimalt at kontrollere inden man indsætter dem. Problemet ligger i at der bliver indsat "kontakter" i contacts hver dag. Disse kontakter kan ha en timestamp der er ændrer end dem der er i forvejen. Jeg kan derfor ikke blot kontrollere når man smider dem op.
I min første kode sletter jeg dem ikke fra contacts igen. Det gør jeg ved efterfølgende at køre: DELETE FROM lcm_contacts WHERE id=ANY(SELECT `id` FROM lcm_doublets)
Jeg vil test det med en ekstra table og se om det er hurtigere lidt senere :)
Det afventer jeg så. Men stadig, du siger, at der indsættes kontakter hver dag. Så der må være en kode såsom INSERT INTO contacts ...... Der forestiller jeg mig, at du kunne kode, der checker om der allerede er en kontakt med det samme firstName. Hvis ja, er timeStamp mindre end den nye timestamp, THEN insert den nye kontakt i doublets ELSE flyt den bestående komntakt til doublets AND insert den nye kontakt i contacts. I så fald får du sat tingene i de rette tabeller fra starten, således at du undgår bestandigt at skulle sortere contacts.
Har du faktisk ret i. Hvis jeg konstant kontrollere med timestamp burde man jo kunne gøre det ved indlæsning. (Jeg er lidt langsom her, beklager)
Lyder som en noget bedre idé. Ser lige om jeg ikke kan gøre det sådan i stedet. Du kan blot smide et svar hvis du vil ha point. (ved ikke om man bruger er mere :P ) Du har været stor hjælp :)
Svar fra mig. (Men måske vil du også invitere svar fra andre.)
Synes godt om
Ny brugerNybegynder
Din løsning...
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.