Sådan bruger du EXPLAIN i MySQL til at forstå og fremskynde forespørgsler

Sidste ændring: 11/28/2025
Forfatter: C SourceTrail
  • EXPLAIN og EXPLAIN ANALYZE afslører MySQLs forespørgselsplan, indeksbrug og estimerede eller faktiske rækkeantal, hvilket gør diagnose af langsomme forespørgsler langt mere præcis.
  • Nøgle EXPLAIN-kolonner som type, possible_keys, key, key_len, rows, filtered og Extra viser adgangsmønstre, indekseffektivitet og skjulte omkostninger såsom filsortering eller midlertidige tabeller.
  • Veldesignede indekser med én og flere kolonner, valideret med EXPLAIN, forvandler komplette tabelscanninger og tunge joins til hurtige, indeksdrevne opslag.
  • EXPLAIN fungerer bedst sammen med solid datamodellering, gennemtænkt arkitektur og overvågningsværktøjer, hvilket sikrer langsigtet, skalerbar MySQL-ydeevne.

FORKLAR brugen i MySQL

Hvis du arbejder med MySQL længe nok, vil du før eller siden støde på en langsom forespørgsel, der ødelægger din dag. Måske en rapport, der aldrig bliver færdig, et API-slutpunkt, der får timeout under belastning, eller et dashboard, der pludselig tager 20 sekunder at indlæse. Når det sker, er det første rigtige fejlfindingsværktøj, du bør bruge, EXPLAIN familie af kommandoer.

MySQL's EXPLAIN og EXPLAIN ANALYZE viser dig, hvordan optimeringsprogrammet planlægger og rent faktisk udfører en forespørgsel. Når de bruges korrekt, afslører de, hvilke tabeller der scannes, hvilke indeks der bruges (eller ignoreres), hvordan joins udføres, hvor mange rækker der undersøges, og hvor tiden rent faktisk bruges. I denne guide vil vi på en letforståelig måde forklare, hvordan man bruger dem, hvordan man læser deres output, og hvordan man omsætter den indsigt til konkrete forbedringer af ydeevnen.

Hvad EXPLAIN gør i MySQL (og hvornår skal det bruges)

I MySQL, EXPLAIN Nøgleordet er et diagnostisk værktøj, der viser den planlagte udførelsesstrategi for en sætning i stedet for at køre den normalt. Du placerer EXPLAIN foran din forespørgsel, og MySQL svarer med en lille tabel, der beskriver, hvordan den har til hensigt at hente de anmodede rækker.

Du kan bruge FORKLARING med SELECT, INSERT, UPDATE, DELETE og REPLACE udsagn, ikke kun SELECT. For eksempel:

Eksempel:

Eksempel på forespørgsel: EXPLAIN SELECT * FROM employees WHERE last_name = 'Puppo' AND first_name = 'Kendra';

I stedet for at returnere medarbejderdata, returnerer MySQL en række-for-række forklaring på, hvordan den pågældende sætning ville udføres. Du vil se hvilken tabel der læses, hvilket indeks der er valgt, hvor mange rækker MySQL forventer at inspicere, og ekstra noter, såsom om en midlertidig tabel eller filsortering er påkrævet.

Brug EXPLAIN, når du har mistanke om, at en forespørgsel er langsommere end den burde være, eller når du designer indeks og vil verificere, at MySQL rent faktisk vil bruge dem. Det er også yderst nyttigt, når du arver kompleks, ældre SQL-kode med flere underforespørgsler og joins, og du er nødt til at reverse engineere, hvad optimeringsprogrammet gør.

Varianter af EXPLAIN: EXTENDED, PARTITIONS, ANALYZE og formater

Den grundlæggende FORKLARING er kun udgangspunktet; MySQL tilbyder adskillige udvidelser og outputformater, der giver mere indsigt. At forstå disse muligheder hjælper dig med at vælge det rette detaljeringsniveau til hver situation.

EXPLAIN EXTENDED tilføjer flere optimeringsoplysninger, især filtered kolonne og omskrevet forespørgselstekst. Efter at have kørt EXPLAIN EXTENDED ... du kan udføre SHOW WARNINGS; for at se, hvordan optimeringsværktøjet omskrev din forespørgsel internt, hvilket er meget praktisk til at forstå optimeringsbeslutninger.

EXPLAIN PARTITIONS viser hvilke partitioner i en partitioneret tabel der vil blive tilgået af forespørgslen. partitions Kolonnen viser de relevante partitioner, hvilket hjælper dig med at verificere, at partitionsbeskæring rent faktisk finder sted, og at du ikke rammer alle partitioner ved et uheld.

Outputformatet er også fleksibelt: du kan få tabelformet, tabulatorsepareret, lodret eller JSON-output i CLI'en og visuelle planer i værktøjer som MySQL Workbench. JSON-output er især nyttigt til automatisering og dybere analyser, fordi det inkluderer omkostningsestimater og indlejret planstruktur, men bemærk at almindelig EXPLAIN ANALYZE I MySQL understøttes i øjeblikket ikke rå JSON-output.

Visuelle værktøjer som MySQL Workbench kan gengive EXPLAIN som et grafisk træ, hvilket ofte er lettere at forstå for komplekse joins og underforespørgsler. Eksterne værktøjer som Percona Toolkit, EverSQL eller Releem kan forbruge EXPLAIN-output eller forsinke forespørgselslogfiler og hjælpe dig med at prioritere, hvilke sætninger der skal optimeres først.

Forståelse af EXPLAIN-kolonnerne (tabelformat)

Når du kører et klassisk EXPLAIN uden JSON-format, returnerer MySQL én række pr. tabel eller underforespørgsel, der er involveret i din sætning. Rækkefølgen af ​​disse rækker er vigtig: den viser den rækkefølge, hvori tabeller tilgås under udførelsen.

Dette er de vigtigste kolonner, du vil se, og hvad de fortæller dig:

  • id: En sekventiel identifikator for hver del af forespørgslen. En enkelt simpel SELECT har normalt id = 1Flere id'er angiver underforespørgsler, afledte tabeller eller UNION-dele. Højere tal udføres generelt før lavere tal, hvilket giver dig et hint om udførelsesrækkefølgen.
  • select_type: Beskriver rollen af ​​den pågældende SELECT i den overordnede forespørgsel, med værdier som SIMPLE (ingen underforespørgsler eller UNION'er), PRIMARY (yderste SELECT i en kompleks forespørgsel), UNION, UNION RESULT, DERIVED (underforespørgsel i FROM) eller fuldtekstrelaterede typer. Dette giver dig et hurtigt overblik over, om du har at gøre med indbyggede forespørgsler, foreninger eller afledte tabeller.
  • table: Angiver hvilken tabel eller hvilket internt resultat denne række refererer til. Det kan være et rigtigt tabelnavn eller et pseudonavn som f.eks. <unionM,N> for et internt UNION-resultat, <derivedN> for en afledt tabel eller lignende markører for materialiserede underforespørgsler.
  • partitions: Når du bruger partitionerede tabeller sammen med EXPLAIN PARTITIONS, denne liste viser de partitioner, der indeholder rækker, der matcher forespørgselsbetingelserne. Hvis du ser mange partitioner på listen, har du muligvis ikke gavn af partitionsbeskæring.
  • type: Dette kaldes ofte join- eller access-typen, og er en af ​​de vigtigste indikatorer for ydeevne. Den beskriver, hvordan MySQL tilgår rækker: værdier spænder fra meget effektive (som const, eq_ref, ref) til mindre effektiv (range) til fattig (index, ALL fuld tabelscanning). Særlige typer som f.eks. index_merge, unique_subqueryog index_subquery angiv specifikke optimeringer.
  • possible_keys: Viser en liste over indekser, som MySQL mener kunne bruges til denne del af forespørgslen. Hvis dette er tilfældet NULL, betyder det, at MySQL ikke ser noget brugbart indeks, hvilket er et stærkt signal om, at du muligvis skal oprette et baseret på dine WHERE- eller JOIN-betingelser.
  • key: Viser det faktiske indeks, som optimeringsværktøjet har valgt for denne adgang. Hvis det er NULL mens possible_keys lister kandidater, besluttede optimeringsprogrammet, at det ikke var umagen værd at bruge et indeks, ofte på grund af lav selektivitet eller lille tabelstørrelse.
  • key_len: Viser antallet af bytes af indekset, der bruges. For sammensatte indekser angiver dette, hvor mange indledende kolonner der effektivt er i spil. Dette er afgørende for at forstå, om dit flerkolonneindeks bruges fuldt ud eller kun delvist.
  • ref: Angiver, hvad der sammenlignes med indekskolonnerne, der er angivet i keyDen kan pege på en anden tabelkolonne (for joins) eller på en konstant (for simple filtre).
  • rows: Et estimat af, hvor mange rækker MySQL forventer at undersøge i dette trin. Det er omtrentligt baseret på statistik, men meget nyttigt til at måle, hvor dyr en forespørgsel vil være, og om et indeks reducerer søgeområdet effektivt.
  • filtered: Fås med EXPLAIN EXTENDED, denne procentdel repræsenterer, hvor mange af de undersøgte rækker der forventes at opfylde betingelserne i den pågældende tabel. Lave procenter kombineret med høje rows skriger ofte efter bedre indeksering eller mere selektive betingelser.
  • Extra: Et fritformet felt, der indeholder ekstra noter, der ikke passer andre steder, f.eks. Using index, Using where, Using temporary, Using filesort, fuldtekst-tips og mere, som alle indeholder vigtige ledetråde til ydeevne.

Ved at læse disse kolonner sammen i stedet for isoleret, får du et kompakt, men effektivt resumé af, hvordan MySQL har til hensigt at opfylde din forespørgsel. Med lidt øvelse vil du hurtigt få øje på røde flag som komplette tabelscanninger, manglende indeks eller unødvendige midlertidige tabeller.

Hvordan EXPLAIN definerer adgangstyper (den type kolonne)

type Kolonnen fortjener særlig opmærksomhed, fordi det er en af ​​de hurtigste måder at vurdere en forespørgsels tilstand på. Selvom dokumentationen kalder det en join-type, er det mere præcist at tænke på det som en adgangstype, der beskriver, hvordan rækker findes.

På et overordnet niveau spænder adgangstyperne fra "fremragende" til "forfærdelig" med hensyn til ydeevne. Selvom den præcise liste er lang, inkluderer de vigtige:

  • const / system: MySQL kan opløse tabellen til højst én række via en primærnøgle eller et unikt indeks med en konstant værdi. Dette er ekstremt effektivt.
  • eq_ref: For hver række fra den forrige tabel læser MySQL præcis én matchende række fra denne tabel, normalt på grund af en unik eller primær nøglereference i en join.
  • ref: MySQL tilgår rækker via et ikke-unikt indeks, der matcher en konstant eller kolonne; flere rækker kan matche. Stadig generelt godt.
  • range: MySQL bruger et indeks til at hente rækker i et givet værdiinterval (f.eks. BETWEEN, >=, eller et præfiks, der matcher med LIKE 'abc%'). Dette er ofte acceptabelt, især for dato- eller numeriske intervaller.
  • index: MySQL scanner hele indekset i stedet for alle tabeldata. Bedre end en fuld tabelscanning, men stadig ofte for dyrt på store indeks.
  • ALL: Fuld tabelscanning. MySQL læser hver række for at finde matches. På små tabeller kan dette være fint, men på store tabeller bør du generelt overveje indeksering eller omskrivning af forespørgsler for at undgå det.
  • index_merge: Indikerer, at MySQL kombinerer resultater fra flere indekser i den samme tabel. Det lyder fint, men i praksis klarer det sig ofte dårligere end et godt enkelt sammensat indeks.
  • unique_subquery / index_subquery: Specielle adgangstyper, der bruges til at optimere bestemte IN (SELECT ...) underforespørgsler via unikke eller ikke-unikke indeksopslag, der erstatter mindre effektive opslagsmønstre.

Når du gennemgår EXPLAIN-outputtet, ønsker du generelt, at adgangstyperne skal være så langt i retning af const / eq_ref / ref som muligt og undgå ALL på store borde. Hvis du ser ALL med en høj rows estimat er det næsten altid en kandidat til bedre indeksering.

Nøgle, possible_keys og key_len: hjælper dine indekser virkelig?

Indekser er ofte den mest effektive måde at fremskynde forespørgsler på, og EXPLAIN hjælper dig med at forstå præcis, hvordan de bruges. Tre kolonner er særligt vigtige for indeksdiagnostik: possible_keys, keyog key_len.

possible_keys viser alle de indekser, som MySQL mener kunne være relevante for den pågældende tabel baseret på WHERE- og JOIN-betingelserne. Hvis dette er tilfældet NULL For en tabel, der deltager i et tungt filter eller en join, er det et stærkt hint om, at du bør overveje at tilføje et indeks, der dækker de relevante kolonner.

key fortæller dig hvilket indeks MySQL rent faktisk valgte blandt kandidaterne. If key is NULL mens der er indlæg i possible_keys, optimeringsværktøjet besluttede, at en fuld scanning er billigere, hvilket normalt indikerer dårlig indeksselektivitet, forældet statistik eller et forespørgselsmønster, der ikke kan drage fordel af det tilgængelige indeksdesign.

key_len viser, hvor mange bytes af det valgte indeks der bruges. For sammensatte indekser giver dette dig mulighed for at bekræfte, hvor mange af de indekserede kolonner der bidrager til søgningen. Hvis du har bygget et indeks på (last_name, first_name) og key_len dækker kun længden for last_name, du ved, at forespørgsler ikke udnytter det sammensatte indeks fuldt ud.

ref Kolonnen supplerer dette ved at fortælle dig, hvad MySQL sammenligner med indekset, om det er en konstant (som 'Puppo') eller en kolonne fra en sammenkædet tabel. Hvis du fejlsøger en join, og du ser den korrekte join-kolonne i ref sammen med en god type værdi såsom eq_ref er et tegn på, at dit join er godt indekseret.

Rækker, filtrerede og ekstra: opdagelse af skjulte ineffektiviteter

rows og filtered kolonner giver en grov idé om arbejdsmængden, mens Extra fremhæver særlige operationer, der ofte forklarer ydeevneproblemer. Disse tre bør altid gennemgås samlet.

rows er MySQLs estimat af, hvor mange poster den skal undersøge i dette trin. Det er ikke altid præcist, men det er godt nok til at opdage åbenlyst dårlige tilfælde, såsom at scanne hundredtusindvis af rækker, når man forventede en håndfuld.

filtered (tilgængelig gennem EXPLAIN EXTENDED) angiver den estimerede procentdel af undersøgte rækker, der vil opfylde betingelserne for den pågældende tabel. En høj rows med en meget lav filtered Procentdelen peger normalt på manglende eller suboptimale indeks eller dårligt selektive prædikater.

Extra Kolonnen aggregerer yderligere noter om udførelsen, der ikke passer andre steder. Nogle af de vigtigste værdier, du kan støde på, inkluderer:

  • Using where: En WHERE-betingelse anvendes til at filtrere rækker for denne tabel.
  • Using index: MySQL kan betjene alle nødvendige kolonner fra indekset alene uden at røre tabeldataene, hvilket er kendt som et dækkende indeks og generelt er meget effektivt.
  • Using temporary: MySQL opretter en intern midlertidig tabel til at indeholde mellemliggende resultater, for eksempel til kompleks GROUP BY- eller underforespørgselsbehandling. På store datasæt kan dette have alvorlig indflydelse på ydeevnen.
  • Using filesort: MySQL udfører et separat sorteringstrin, ofte for ORDER BY eller GROUP BY, hvilket kan udføres i hukommelsen eller på disken og normalt er dyrere end at bruge en indeksbaseret rækkefølge.
  • Fuldtekstrelaterede noter: Når man bruger FULLTEXT-indekser, kan EXPLAIN afsløre, om en fuldtekstsøgning kombineres korrekt med joins eller andre filtre.

Vær særlig opmærksom på Using temporary og Using filesort in Extra når forespørgsler er langsomme, da begge dele kan indikere tungt sorterings- eller grupperingsarbejde, der kan blive omplaceret til bedre indekser eller omstrukturerede forespørgsler.

FORKLAR ANALYSER: at se de reelle udførelsesomkostninger

Fra og med MySQL 8.0.18 får du et endnu mere kraftfuldt værktøj: EXPLAIN ANALYZE, som rent faktisk kører forespørgslen og knytter kørselsstatistik til planen. Dette bygger bro mellem teoretiske omkostningsestimater og den faktiske ydeevne.

I modsætning til den almindelige EXPLAIN, som kun forudsiger, udfører EXPLAIN ANALYZE sætningen og måler, hvor lang tid hver iterator (trin) i planen tager, hvor mange rækker den returnerer, og hvor mange løkker den udfører. Syntaksen er ligetil:

Løb: EXPLAIN ANALYZE SELECT * FROM table_name WHERE condition;

Når du kører EXPLAIN ANALYZE, bruger MySQL FORMAT=tree automatisk og udgiver en træformet plan, der kombinerer estimerede og faktiske målinger. For hver node kan du se:

  • Estimeret udførelsesomkostning: Optimeringsmodellen for, hvor dyrt dette trin bør være.
  • Estimerede rækker: Hvor mange rækker forventedes returneret fra denne iterator.
  • Faktisk tid til første række: Hvor lang tid det tog, før den første række blev produceret.
  • Faktisk tid brugt pr. loop: Gennemsnitlig tid i millisekunder til at udføre iteratoren, inklusive dens underordnede, men ikke dens overordnede, på tværs af løkker.
  • Faktiske rækker og løkker: Hvor mange rækker blev virkelig returneret, og hvor mange gange iteratoren kørte.

Du kan bruge EXPLAIN ANALYZE med SELECT-, multi-table UPDATE-, DELETE- og TABLE-sætninger. Det er især nyttigt, når den normale EXPLAIN foreslår én ting, men forespørgslen stadig opfører sig anderledes i produktion, fordi du nu kan sammenligne estimerede vs. faktiske rækkeantal og omkostninger.

Store uoverensstemmelser mellem estimater og faktiske værdier afslører, hvor optimeringsprogrammets statistikker er forkerte, eller hvor komplekse prædikater (herunder funktioner, UDF'er eller lagrede rutiner) gør omkostningsforudsigelser unøjagtige. Disse steder er primære mål for skemajusteringer, nye indeks eller omskrivning af forespørgsler.

Klassisk EXPLAIN vs. EXPLAIN ANALYZE: styrker og begrænsninger

Selvom EXPLAIN og EXPLAIN ANALYZE er utroligt nyttige, er det vigtigt at forstå deres blinde vinkler, så du ikke overfortolker outputtet.

Almindelig EXPLAIN er i bund og grund en tilnærmelse af, hvad optimeringsværktøjet tror vil ske. Nogle af statistikkerne er grove estimater, og visse interne optimeringer vises slet ikke i outputtet. For eksempel fortæller den dig ikke, hvordan triggere, lagrede funktioner eller brugerdefinerede funktioner påvirker CPU-tiden. Den viser heller ikke, hvad der sker i lagrede procedurer.

Nogle betegnelser i outputtet er en overforenkling af, hvad der virkelig foregår. For eksempel er den type kolonne kaldes en join-type, selvom den i virkeligheden repræsenterer adgangstypen. Extra værdi Using temporary skelner ikke mellem midlertidige tabeller i hukommelsen og på disken, og Using filesort dækker både hukommelses- og diskbaserede typer under samme betegnelse.

EXPLAIN ANALYZE løser nogle af disse problemer ved at vise reel timing og rækkeantal, men det har også kompromiser. Den skal udføre forespørgslen, hvilket kan være dyrt eller endda farligt i produktionen, hvis forespørgslen er ressourcekrævende eller ændrer data. Desuden er rå JSON-output i øjeblikket ikke direkte tilgængeligt for EXPLAIN ANALYZE, så du vil primært arbejde med træformatet i CLI eller klientværktøjer.

Den rigtige tilgang er at bruge EXPLAIN til hurtig og skånsom indsigt i planen og EXPLAIN ANALYZE til dybere undersøgelser, hvor du rent faktisk har råd til at køre forespørgslen.

Brug af EXPLAIN og EXPLAIN ANALYZE til at optimere rigtige forespørgsler

Det er kun nyttigt at læse EXPLAIN, hvis det fører til bedre forespørgsler; nøglen er at oversætte det, du ser, til specifikke indeks- og SQL-ændringer. Lad os gennemgå nogle almindelige optimeringsscenarier, som du kan håndtere direkte med hjælp fra EXPLAIN.

Forestil dig en simpel forespørgsel på en employees tabel uden relevante indekser:

Filtereksempel: EXPLAIN SELECT * FROM employees WHERE last_name = 'Puppo' AND first_name = 'Kendra';

Uden indekser vil EXPLAIN sandsynligvis vise type = ALL og en meget stor værdi i rows (for eksempel omkring 299,000 rækker), hvilket indikerer en fuld tabelscanning. Det er et klart signal om, at du har brug for et indeks, der understøtter begge betingelser.

En naiv tilgang er at oprette to separate indekser, et på last_name og en på first_name, men det gør stadig ikke kombinationssøgningen effektiv. MySQL kan hurtigt finde alle med last_name = 'Puppo' eller alle med first_name = 'Kendra', men at identificere præcis rækken 'Kendra Puppo' kræver, at disse sæt krydses, hvilket ikke er så effektivt, som man måske håber.

Den bedre løsning er et indeks med flere kolonner, der følger dit mest selektive og hyppigt anvendte søgemønster:

Oprettelse af indeks: CREATE INDEX fullnames ON employees(last_name, first_name);

Hvis du kører EXPLAIN igen nu, bør du se, at dette indeks bruges, type forbedres til noget i retning af ref eller endda const afhængigt af unikhed, og rows falder til 1. Dette bekræfter, at kun én række skal berøres, hvilket forklarer den massive forbedring af ydeevnen.

Et lignende mønster ses i join-optimering. Antag, at du har to tabeller A og B med en delt kolonne X, der bruges til sammenkædning, og du opretter dem oprindeligt uden indekser:

Skema: CREATE TABLE A ( X VARCHAR(10), Y VARCHAR(10));
CREATE TABLE B ( X VARCHAR(10), Z VARCHAR(10));

Kørsel af en join med et filter på AX kan vise fulde scanninger på både A og B, hver med omkring 10,000 undersøgte rækker, fordi motoren ikke har nogen bedre mulighed end at brute-force sammenligne rækker:

Forespørgsel om tilmelding: EXPLAIN SELECT *
FROM A INNER JOIN B ON A.X = B.X
WHERE A.X = '100';

Når du har tilføjet passende indekser og fremmednøglebegrænsninger, afspejler EXPLAIN den forbedrede strategi. For eksempel:

Indeks & FK: CREATE UNIQUE INDEX a_unique_index ON A(X);
CREATE UNIQUE INDEX b_unique_index ON B(X);
ALTER TABLE B ADD CONSTRAINT fk_b_x FOREIGN KEY (X) REFERENCES A(X);

Efter disse ændringer vil EXPLAIN typisk vise type forbedring (f.eks. eq_ref på den sammenføjede tabel), samt rows falder fra tusinder til omkring 1, hvilket beviser, at join'et nu bruger effektive indeksopslag i stedet for at scanne alt.

Mønstermatchning, sortering og andre almindelige faldgruber

EXPLAIN er især værdifuldt, når man har med mønstre, sorteringer og grupperinger at gøre, hvor tilsyneladende harmløs SQL fuldstændigt kan deaktivere indekser. At genkende disse mønstre tidligt sparer dig for en masse gætteri.

Et klassisk problem er mønstermatchning med indledende jokertegn. For eksempel en forespørgsel med WHERE email LIKE '%yahoo.com' gør det umuligt for et standardindeks på email for at hjælpe, fordi MySQL ikke har nogen måde at hoppe direkte til rækker, der ender med det suffiks. EXPLAIN vil typisk vise type = ALL og en stor rows tælle.

Efterfølgende jokertegn, som f.eks. LIKE 'john%', er indeksvenlige, fordi søgemaskinen kan bruge indekset til at finde rækkevidden af ​​rækker, der starter med 'john'. EXPLAIN vil bekræfte dette ved at vise en god adgangstype og en lille rows estimat på den indekserede kolonne.

Sortering og gruppering er et andet højt prioriteret område inden for performance. Hvis EXPLAIN vises Using filesort in Extra sammen med en stor rows estimat, gennemtvinger din ORDER BY eller GROUP BY sandsynligvis et eksplicit sorteringstrin.

Eksempel på sortering: EXPLAIN SELECT sale_id FROM sales ORDER BY sale_date;

Tilføjelse af et indeks på sale_date tillader MySQL at læse rækker direkte i sorteret rækkefølge, hvilket EXPLAIN normalt afspejler ved at fjerne Using filesort og muligvis ændre adgangstypen til index eller bedre.

Samtidig skal du være forsigtig med ikke at overindeksere. EXPLAIN kan vise dig, hvilke indeks der vises i possible_keys men bruges aldrig som key af enhver vigtig forespørgsel. Disse kan være kandidater til fjernelse, men du skal først kontrollere den samlede arbejdsbyrde; bare fordi én forespørgsel ignorerer et indeks, betyder det ikke, at andre kritiske forespørgsler ikke er afhængige af det.

VIS ADVARSLER og udvidede forklaringsmarkører

Når en EXPLAINed-forespørgsel ikke engang parser korrekt, kan du stadig udtrække noget indsigt ved hjælp af SHOW WARNINGS;. Denne kommando viser oplysninger om den sidste ikke-diagnostiske sætning og kan give dig delvise hints om, hvordan MySQL fortolkede fragmenter af din forespørgsel.

Hvis du for eksempel kører EXPLAIN på en forespørgsel, der refererer til en ikke-eksisterende tabel eller indeholder en syntaksfejl, kan EXPLAIN muligvis mislykkes, men SHOW WARNINGS kan stadig vise interne markører, der angiver, hvordan dele af forespørgslen vil blive behandlet. Du kan muligvis se markører som:

  • <index_lookup>(query fragment): antyder, at der ville blive udført et indeksopslag for det fragment, hvis forespørgslen var gyldig.
  • <primary_index_lookup>(query fragment): angiver, at der ville forekomme et opslag baseret på en primærnøgle.
  • <if>(condition, expr1, expr2): påpeger betinget evaluering i den del af forespørgslen.
  • <temporary table>: angiver oprettelse af en intern midlertidig tabel til mellemliggende resultater, for eksempel før en joining.

At kombinere EXPLAIN EXTENDED med SHOW WARNINGS er en effektiv måde at se ikke kun planen, men også optimeringsværktøjets omskrevne forespørgsel, som nogle gange afslører forenklinger, prædikat-pushdown eller andre transformationer, du måske ikke forventer.

Ud over EXPLAIN: datamodel, arkitektur og værktøjer

Selvom EXPLAIN er et fantastisk mikroskop til individuelle forespørgsler, afhænger bæredygtig ydeevne også af din overordnede datamodel, systemarkitektur og hardware. Du kan ikke reparere et fundamentalt dårligt skema eller en overbelastet instans udelukkende ved at justere where-klausuler.

Et godt udgangspunkt er en datamodel, der adskiller meget forskellige arbejdsbyrder og JSON-behandling i SQL. For eksempel er det at blande adgangslogfiler med store mængder og transaktionsdata i den samme MySQL-instans en opskrift på langvarig smerte: Efterhånden som virksomheden vokser, kan logføring af trafik mætte I/O og forringe kritiske forretningsforespørgsler. Opdeling af logfiler i et dedikeret lager eller datalager er ofte mere skalerbart.

Softwarearkitektur spiller også en stor rolle. Beslutninger om monolit vs. mikrotjenester, data warehouses og specialiserede butikker (som grafdatabaser til anbefalinger) vil påvirke, hvilken slags forespørgsler du kører, og hvor. Hvis en tjeneste har brug for næsten realtidsanalyse på enorme datasæt, er en standard OLTP MySQL-instans muligvis ikke det bedste mål for disse forespørgsler.

Hardware og instansstørrelse har også betydning. Disk-I/O, hukommelse, CPU og netværksgennemstrømning påvirker alle forespørgselsforsinkelser. Identifikation af perioder med spidsbelastning og planlægning af tunge analytiske eller administrative forespørgsler uden for disse vinduer kan beskytte brugervendt ydeevne. Med administrerede DBaaS-tilbud kan du ofte skalere instanser eller flytte til mere effektive klasser efter behov.

Endelig skal EXPLAIN suppleres med løbende overvågnings- og profileringsværktøjer. MySQLs eget performanceskema og langsomme forespørgselslog, MySQL Workbench, Percona Toolkits pt-query-digest, webværktøjer som EverSQL og platforme som Releem kan automatisk afdække dine værste syndere og endda foreslå optimeringer. EXPLAIN er derefter dit kirurgiske værktøj til disse specifikke forespørgsler.

Ved at tilføje EXPLAIN og EXPLAIN ANALYZE til din værktøjskasse kan du stoppe med at gætte om langsomme forespørgsler og begynde at ræsonnere med konkrete beviser. Ved at forstå id'er, select-typer, adgangsmetoder, indeksbrug, rækkeestimater, filtre og ekstra flag kan du metodisk fjerne fulde tabelscanninger, tæmme dyre joins, designe smartere indeks og undgå spild af sorteringer og midlertidige tabeller, alt imens du holder øje med det større billede af skemadesign og infrastruktur, så dine MySQL-arbejdsbelastninger forbliver hurtige og forudsigelige, efterhånden som de vokser.

JSON-behandling i SQL
relateret artikel:
Procesamiento de JSON en SQL: Funciones, consultas y rendimiento
Relaterede indlæg: