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

Hastighed for IN nøgleord i MySQL/PostgreSQL

I PostgreSQL afhænger præcis, hvad du får her af den underliggende tabel, så du bør bruge EXPLAIN ANALYZE på nogle eksempelforespørgsler mod en nyttig delmængde af dine data for at finde ud af præcis, hvad optimeringsværktøjet skal gøre (sørg for, at tabellerne du 're kører imod er også blevet ANALYSERET). IN kan behandles på et par forskellige måder, og det er derfor, du skal se på nogle eksempler for at finde ud af, hvilket alternativ der bliver brugt til dine data. Der er ikke noget simpelt generisk svar på dit spørgsmål.

Med hensyn til det specifikke spørgsmål, du tilføjede i din revision, mod et trivielt datasæt uden involverede indekser er her et eksempel på de to forespørgselsplaner, du får:

postgres=# explain analyze select * from x where s in ('123','456');
 Seq Scan on x  (cost=0.00..84994.69 rows=263271 width=181) (actual time=0.015..1819.702 rows=247823 loops=1)
   Filter: (s = ANY ('{123,456}'::bpchar[]))
 Total runtime: 1931.370 ms

postgres=# explain analyze select * from x where s='123' or s='456';
 Seq Scan on x  (cost=0.00..90163.62 rows=263271 width=181) (actual time=0.014..1835.944 rows=247823 loops=1)
   Filter: ((s = '123'::bpchar) OR (s = '456'::bpchar))
 Total runtime: 1949.478 ms

Disse to kørselstider er i det væsentlige identiske, fordi den reelle behandlingstid er domineret af den sekventielle scanning henover bordet; kører flere gange viser forskellen mellem de to er under kørslens fejlmargin. Som du kan se, transformerer PostgreSQL IN-casen til at bruge dens ANY filter, som altid skal køre hurtigere end en række OR'er. Igen, denne trivielle sag er ikke nødvendigvis repræsentativ for, hvad du vil se på en seriøs forespørgsel, hvor indekser og lignende er involveret. Uanset hvad burde det aldrig være hurtigere at manuelt erstatte IN'er med en række OR-sætninger, fordi optimeringsværktøjet ved, hvad det er bedst at gøre her, hvis den har gode data at arbejde med.

Generelt kender PostgreSQL flere tricks til, hvordan man optimerer komplicerede forespørgsler, end MySQL-optimizeren gør, men den er også meget afhængig af, at du har givet optimizeren nok data til at arbejde med. De første links i afsnittet "Performance Optimization" i PostgreSQL-wikien dækker de vigtigste ting, der er nødvendige for at få gode resultater fra optimeringsværktøjet.



  1. MySQL:Ugyldige GIS-data leveret til funktion st_geometryfromtext

  2. Den nemmeste måde at tilføje flere mellemrum til en streng i MySQL – SPACE()

  3. MySQL-filter på mange-til-mange

  4. Er der et trick til at tillade MySQL at ignorere et efterfølgende komma i SET-sætningen i en UPDATE-sætning?