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

Forespørgselsydelsesoptimering i MySQL

Eksperter ved, hvordan man skriver præstationseffektive forespørgsler. Selvom erfaring modner visdom, er der visse ting, som man i det mindste skal forstå til at begynde med. For eksempel skal du forstå centrale overvejelser ved forespørgselsdesign; hvordan en forespørgsel fungerer internt, hvor den fejler, optimeringsmønstre osv. I denne artikel vil jeg give et par optimeringspunkter at overveje, mens jeg designer en forespørgsel i MySQL.

Hvorfor er nogle forespørgsler langsomme?

Et almindeligt problem med SQL-forespørgsler er, at der hentes flere data, end der reelt er brug for. Selvfølgelig er der forespørgsler, der gennemskærer en masse data, og vi kan ikke gøre meget ved dem, men de er ikke almindelige. I de fleste tilfælde er det dårligt forespørgselsdesign, der fører til dårlig forespørgselsydeevne. Efter hvert forespørgselsdesign skal du introspektere et par aspekter, såsom hvad der kunne ske, efter at forespørgslen er udløst:

  1. Vil SQL-forespørgslen få adgang til for mange kolonner eller rækker?
  2. Vil MySQL-serveren analysere for mange rækker til at hente det ønskede resultat?

Der er forespørgsler, der får MySQL-serveren til at analysere for meget data, men kaster dem, mens den sigter. Dette er et ekstra arbejde for serveren i form af mange aspekter såsom netværksoverhead, for meget hukommelsesforbrug eller for meget CPU-ressourceforbrug på serveren. Konsekvensen er langsom ydeevne.

Der er situationer, hvor du måske ikke kan hjælpe meget under dets design, men der er en situation, hvor hvis du er omhyggelig og vurderer konsekvensen og introspektiv, så kan en dårlig forespørgsel i det mindste gøres god, hvis ikke bedre.

Typiske fejl og deres løsninger

Der er en del almindelige fejl, der ofte begås, mens du skriver en forespørgsel. Her er et par af dem. Du kan finde et par flere tanker på samme linje. Her er grunde til langsom forespørgselsydeevne med mulige løsninger.

For mange rækker

Fejlen begås ofte ved at skrive en forespørgsel, der henter data og antage, at MySQL vil levere resultater efter behov, mens den overser mængden af ​​behandling, der kræves for at returnere det fulde resultatsæt. Antag, at en SELECT-sætning udløses for at hente 100 produktdetaljer for et e-handelssted, når kun 10 af dem faktisk skal vises først. Du tror måske, at MySQL kun henter 10 rækker og stopper med at udføre forespørgslen. Men nej. Hvad MySQL gør, er at generere det komplette resultatsæt og fodre klienten. Klientbiblioteket modtager det komplette sæt og kasserer det meste og beholder kun 10, hvoraf det søger. Dette spilder helt klart en masse ressourcer.

Men i en sådan situation kan du give en løsning ved at bruge LIMIT-sætningen med forespørgslen.

SELECT
      col1, col2,...
FROM
      table_name
LIMIT
      [offset,] count; 

LIMIT-sætningen accepterer en eller to parametre. Den første specificerer offset, og den anden specificerer tæller. Hvis kun én parameter er angivet, angiver den antallet af rækker fra begyndelsen af ​​resultatsættet.

For eksempel, for at vælge 10 rækker fra tabellen, kan du skrive:

SELECT
      e.emp_name, e.phone, e.email
FROM 
      employee e
LIMIT 10;

Og for at vælge de næste 10 rækker, startende fra 11 post, kan du skrive:

SELECT
      e.emp_name, e.phone, e.email
FROM
      employee e
LIMIT 10, 10;

For mange kolonner

Se altid på forespørgslen:SELECT * med mistanke. Denne forespørgsel returnerer alle kolonner, og du har sandsynligvis kun brug for nogle af dem. Den største ulempe ved at hente alle kolonner er, at det forhindrer optimering ved at hindre brugen af ​​indekser, kræver for meget I/O, hukommelse og CPU-ressourcer fra serveren.

Forstå, at sådan en universel forespørgsel, der henter alle kolonner, kan være spild. Nogle siger, at de er nyttige, fordi det lader udvikleren bruge den samme kodebit mere end ét sted. Det er fint, hvis de involverede omkostninger er begrænset i betragtning. Nogle gange hjælper caching af hentede data i denne sammenhæng. Men vær dog forsigtig, at udnytte ydeevne er et slankt job, og sådan luksus har måske ikke et sted for ydeevne.

Tommelfingerreglen er at undgå sådanne universelle forespørgsler eller holde et antal kolonner hentet så minimalt som muligt.

For meget dataanalyse

Forespørgsler returnerer det ønskede resultat, det er fint, men nogle gange er disse forespørgsler skrevet på en sådan måde, at det under behandlingen kræver at undersøge for mange data, før de genererer resultater. Derfor skal du i MySQL måle efter følgende omkostningsmålinger:

  • Udførelsestid
  • Rækker undersøgt
  • Kolonner undersøgt

Du kan få et groft skøn over forespørgselsomkostninger fra disse målinger. Disse afspejler mængden af ​​dataadgang fra MySQL internt til at behandle forespørgslen, og hvor hurtigt forespørgslen kører. Da disse metrics logges i den langsomme forespørgselslog, er det en god idé at undersøge og finde forespørgsler, der analyserer for meget data til at returnere resultatet. MySQL-databasen registrerer alle forespørgsler, der overskrider en given mængde af eksekveringstid i langsom forespørgselslog. Dette er et ideelt sted at lede efter langsomme forespørgsler og finde ud af, hvor ofte de er langsomme.

En langsom forespørgselslog er typisk placeret på /var/log/mysql/mysql-slow.log

Bemærk, at man muligvis skal indstille og aktivere logning af langsomme forespørgsler i mysqld.cnf konfigurationsfil som følger.

#slow_query_log = 1
#slow_query_log_file = /var/log/mysql/mysql-slow.log
#long_query_time = 2 

Før og med MySQL 5 var der alvorlige begrænsninger, især manglende støtte til finkornet logning. Eneste pusterum var at bruge patches, der aktiverede logning. Funktionen har dog været en del af MySQL 5.1 og senere servere som en del af dens kernefunktion.

Forespørgsler, der tager for lang tid at udføre, betyder ikke nødvendigvis, at de er dårlige forespørgsler. Den langsomme forespørgselslog giver simpelthen mulighed for at undersøge forespørgselsydelsen og forbedre den som muligt.

Omstruktureringsforespørgsler

Da du har mulighed for at omstrukturere problematiske forespørgsler, bør dit primære mål være at finde en alternativ løsning for at opnå den effekt, vi ønsker. Du kan transformere forespørgslen til dens tilsvarende form under hensyntagen til den interne effekt i MySQL-serveren under behandlingen.

En beslutning i forespørgselsdesign er, om vi skal favorisere én kompleks forespørgsel i stedet for flere simple eller omvendt. Den konventionelle tilgang til databasedesign er at udføre så mange værker som muligt med færre forespørgsler. Årsagen er, at én stor/kompleks forespørgsel er mere omkostningseffektiv med hensyn til etablering af databaseforbindelse. Fordelen ved omkostningsreduktion til fordel for kompleks forespørgsel er netværksbrug, forespørgselsbehandling/optimering og ressourceudnyttelse. Men denne traditionelle tilgang passer ikke godt sammen med MySQL. MySQL er designet til at håndtere databaseforbindelse og afbrydelse hurtigt. Derfor virker det mere effektivt at etablere forbindelse, affyre mange enklere forespørgsler og lukke forbindelsen. Det er mere effektivt at hente data gennem mere end én simpel forespørgsel i stedet for én stor kompleks. Bemærk, at samme idé muligvis ikke anvendes med andre databaser.

Konklusion

Dette er et par hurtige tips til at forespørge om optimering. Forstå, at ved at kende SQL-syntakser, er det ikke nok at skabe en forespørgsel, der henter det ønskede resultat, hvis man sigter efter forespørgselsydeevne. At forstå, hvad der sker under de tilsyneladende simple forespørgsler, er afgørende for at skrive en, der ikke kun henter det ønskede, men gennemsyrer kunsten at optimere lige fra, hvor det hele starter. Bag scenen med forespørgselsbehandling giver et vigtigt fingerpeg om at forstå forespørgselsydeevne, og denne viden er et must, før man går ind i forespørgselsoptimeringsområdet.


  1. Oprettelse af en database i Cloud Sites

  2. Hurtige tips til reparation og gendannelse af SQL-database uden sikkerhedskopiering

  3. SQL Server Database Snapshots -4

  4. Hvordan bruger jeg alias i where-klausulen?