sql >> Database teknologi >  >> RDS >> Mysql

Hvordan ekko tilfældige rækker fra databasen?

To løsninger præsenteret her. Begge disse foreslåede løsninger er MySQL-kun og kan bruges af ethvert programmeringssprog som forbruger. PHP ville være vildt for langsom til dette, men det kunne være forbrugeren af ​​det.

Hurtigere løsning :Jeg kan bringe 1000 tilfældige rækker fra en tabel med 19 millioner rækker på omkring 2 tiendedele af et sekund med mere avancerede programmeringsteknikker.

Langsommere løsning :Det tager omkring 15 sekunder med programmeringsteknikker uden effekt.

Begge bruger i øvrigt datagenereringen set HER som jeg skrev. Så det er mit lille skema. Jeg bruger det, fortsæt med TO flere selvindsættelser set derovre, indtil jeg har 19M rækker. Så det vil jeg ikke vise igen. Men for at få de 19 mio. rækker, gå og se det, og lav 2 flere af disse indsætninger, og du har 19 mio. rækker.

Langsommere version først

Først den langsommere metode.

vælg id,ting fra vurderingsorden efter rand()-grænse 1000; 

Det returnerer 1000 rækker på 15 sekunder.

Hurtigere løsning

Dette er lidt mere kompliceret at beskrive. Essensen af ​​det er, at du forudberegner dine tilfældige tal og genererer en in-klausul slut af tilfældige tal, adskilt af kommaer og pakket ind med et par parenteser.

Det vil se ud som (1,2,3,4) men den vil have 1000 numre i sig.

Og du gemmer dem og bruger dem én gang. Som en engangspude til kryptografi. Ok, ikke en stor analogi, men du forstår pointen, håber jeg.

Tænk på det som en slutning på en in klausul og gemt i en TEXT-kolonne (som en klat).

Hvorfor i alverden skulle man ønske at gøre dette? Fordi RNG (tilfældige talgeneratorer) er uoverkommeligt langsomme. Men at generere dem med nogle få maskiner kan være i stand til at skrue tusinder ud relativt hurtigt. Forresten (og du vil se dette i strukturen af ​​mine såkaldte bilag, jeg fanger, hvor lang tid det tager at generere en række. Cirka 1 sekund med mysql. Men C#, PHP, Java, alt kan sætte det sammen. Pointen er ikke, hvordan du sætter det sammen, snarere, at du har det, når du vil have det.

Denne strategi, den lange og korte af den er, når den kombineres med at hente en række, der ikke er blevet brugt som en tilfældig liste, markere den som brugt og udsende et opkald som f.eks.

vælg id,ting fra vurderinger, hvor id i (a,b,c,d,e, ... ) 

og in-klausulen har 1000 numre, er resultaterne tilgængelige på mindre end et halvt sekund. Effektiv anvendelse af mysql CBO (omkostningsbaseret optimering) end behandler det som en joinforbindelse på et PK-indeks.

Jeg forlader dette i opsummerende form, fordi det er lidt kompliceret i praksis, men inkluderer følgende partikler potentielt

  • en tabel med de forudberegnede tilfældige tal (bilag A)
  • en mysql oprette begivenhedsstrategi (bilag B)
  • en lagret procedure, der medarbejder en Udarbejdet Erklæring (Bilag C)
  • en mysql-kun lagret proc til at demonstrere RNG in klausul for spark (bilag D)

Bilag A

En tabel med de forudberegnede tilfældige tal

opret tabel randomsToUse( -- opret en tabel med 1000 tilfældige tal at bruge -- formatet vil være som en lang "(a,b,c,d,e, ...)" streng -- pre -beregnet tilfældige tal, hentet efter behov for brug id int auto_increment primærnøgle, brugt int ikke null, -- 0 =ikke brugt endnu, 1=brugt dtStartCreate datetime ikke null, -- næste to linjer til øjeæblet tid brugt på at generere denne række dtEndCreate datetime not null, dtUsed datetime null, -- hvornår blev det brugt txtInString text not null -- her er din i klausul ender som (a,b,c,d,e, ...) -- dette kan kun have omkring 5000 rækker og affald renset -- så vælg måske et eller to indekser mere, såsom kompositter); 

Bilag B

For ikke at gøre dette til en bog, se mit svar HER for en mekanisme til at køre en tilbagevendende mysql-begivenhed. Det vil drive vedligeholdelsen af ​​bordet set i appendiks A ved hjælp af teknikker set i appendiks D og andre tanker, du ønsker at drømme op. Såsom genbrug af rækker, arkivering, sletning, hvad som helst.

Bilag C

gemt procedure for simpelthen at få mig 1000 tilfældige rækker.

DROP PROCEDURE hvis eksisterer showARandomChunk;DELIMITER $$CREATE PROCEDURE showARandomChunk()BEGIN DECLARE i int; DECLARE txtInClause-tekst; -- vælg nu() i dtBegin; vælg id,txtInString i i,txtInClause fra randomsToUse, hvor used=0 rækkefølge efter id-grænse 1; -- vælg txtInClause som sOut; -- bruges til debugging -- hvis jeg kører denne følgende sætning, er det 19,9 sekunder på min Dell bærbare computer -- med 19M rækker -- vælg * fra vurderingsrækkefølge efter rand() limit 1000; -- 19 sekunder -- men hvis jeg kører følgende "Forberedt erklæring", hvis tager 2 tiendedele af et sekund -- for 1000 rækker sæt @s1=concat("vælg * fra vurderinger hvor id i ",txtInClause); FORBERED stmt1 FRA @s1; UDFØR stmt1; -- kør hvalpen og giv mig 1000 rækker DEALLOCATE PREPARE stmt1;END$$DELIMITER; 

Bilag D

Kan flettes sammen med Appendiks B koncept. Uanset hvad du vil gøre det. Men det efterlader dig med noget at se, hvordan mysql kunne gøre det helt af sig selv på RNG-siden af ​​tingene. For øvrigt, for parameter 1 og 2 er henholdsvis 1000 og 19M, tager det 800 ms på min maskine.

Denne rutine kunne skrives på et hvilket som helst sprog som nævnt i begyndelsen.

slip procedure, hvis eksisterer createARandomInString;DELIMITER $$create procedure createARandomInString(nHowMany int, -- hvor mange numre du vil have nMaxNum int -- max af ethvert tal)BEGIN ERKLÆR dtBegynd datotid; ERKLÆR dtEnd datetime; DECLARE i int; DECLARE txtInClause-tekst; vælg nu() i dtBegin; sæt i=1; sæt txtInClause="("; MENS i 

Sådan kalder du ovenstående lagrede proc:

kald createARandomInString(1000,18000000); 

Det genererer og gemmer 1 række med 1000 numre pakket som beskrevet ovenfor. Store tal, 1 til 18 mio.

Som en hurtig illustration, hvis man skulle ændre den lagrede proc, skal du fjerne rem linjen nær bunden, der siger "brugt til fejlretning", og have det som den sidste linje i den lagrede proc, der kører, og køre dette:

kald createARandomInString(4,18000000); 

... for at generere 4 tilfældige tal op til 18M, kan resultaterne se ud som

+--------------------------------------------+| minOutput |+---------------------------------------------+| (2857561,5076608,16810360,14821977) |+-------------------------------------------+

Bilag E

Virkelighedstjek. Det er noget avancerede teknikker, og jeg kan ikke undervise nogen i dem. Men jeg ville alligevel dele dem. Men jeg kan ikke lære det. Igen og ud.



  1. xampp MySQL starter ikke

  2. Data fra to tabeller med samme kolonnenavne

  3. nogen grænse for antallet af SQL Server-forbindelser?

  4. SQL:Hvordan kan jeg kun opdatere en værdi på en kolonne, hvis denne værdi er null?