MySQL-databasens arbejdsbelastning bestemmes af antallet af forespørgsler, den behandler. Der er flere situationer, hvor MySQL-langsomhed kan opstå. Den første mulighed er, hvis der er nogen forespørgsler, der ikke bruger korrekt indeksering. Når en forespørgsel ikke kan gøre brug af et indeks, skal MySQL-serveren bruge flere ressourcer og tid på at behandle forespørgslen. Ved at overvåge forespørgsler har du mulighed for at lokalisere SQL-kode, der er grundårsagen til en opbremsning og rette op på det, før den overordnede ydeevne forringes.
I dette blogindlæg vil vi fremhæve funktionen Query Outlier, der er tilgængelig i ClusterControl, og se, hvordan den kan hjælpe os med at forbedre databasens ydeevne. Generelt udfører ClusterControl MySQL-forespørgselssampling på to måder:
- Hent forespørgslerne fra præstationsskemaet (anbefales ).
- Parse indholdet af MySQL Slow Query.
Hvis ydeevneskemaet er deaktiveret, vil ClusterControl derefter som standard bruge logfilen for langsom forespørgsel. For at lære mere om, hvordan ClusterControl udfører dette, tjek dette blogindlæg, Sådan bruger du ClusterControl Query Monitor til MySQL, MariaDB og Percona Server.
Hvad er Outliers for forespørgsler?
En outlier er en forespørgsel, der tager længere tid end den normale forespørgselstid af den type. Tag ikke dette bogstaveligt som "dårligt skrevne" forespørgsler. Det bør behandles som potentielle suboptimale almindelige forespørgsler, der kunne forbedres. Efter et antal prøver, og når ClusterControl har haft nok statistik, kan den afgøre, om ventetiden er højere end normalt (2 sigmas + gennemsnits_forespørgsel_tid), så er den en udligger og vil blive tilføjet til forespørgselsudliggeren.
Denne funktion er afhængig af Top Queries-funktionen. Hvis Forespørgselsovervågning er aktiveret, og Topforespørgsler er fanget og udfyldt, vil Forespørgsels Outliers opsummere disse og give et filter baseret på tidsstempel. For at se listen over forespørgsler, der kræver opmærksomhed, skal du gå til ClusterControl -> Query Monitor -> Query Outliers og skulle se nogle forespørgsler på listen (hvis nogen):
Som du kan se fra skærmbilledet ovenfor, er outliers dybest set forespørgsler, der tog mindst 2 gange længere tid end den gennemsnitlige forespørgselstid. Først den første indtastning, den gennemsnitlige tid er 34,41 ms, mens outlierens forespørgselstid er 140 ms (mere end 2 gange højere end den gennemsnitlige tid). Tilsvarende for de næste poster er kolonnerne Forespørgselstid og Gennemsnitlig forespørgselstid to vigtige ting til at retfærdiggøre udeståendet af en bestemt afvigende forespørgsel.
Det er relativt nemt at finde et mønster af en bestemt forespørgselsudligner ved at se på en større tidsperiode, som for en uge siden, som fremhævet i følgende skærmbillede:
Ved at klikke på hver række kan du se hele forespørgslen, som virkelig er nyttigt at lokalisere og forstå problemet, som vist i næste afsnit.
Reparering af forespørgselsudfaldene
For at rette op på afvigelserne er vi nødt til at forstå forespørgslens art, tabellernes lagermotor, databaseversionen, klyngetype og hvor virkningsfuld forespørgslen er. I nogle tilfælde er outlier-forespørgslen ikke rigtig forringende for den overordnede databaseydeevne. Som i dette eksempel har vi set, at forespørgslen har stået ude i hele ugen, og det var den eneste forespørgselstype, der blev fanget, så det er sandsynligvis en god idé at rette eller forbedre denne forespørgsel, hvis det er muligt.
Som i vores tilfælde er outlier-forespørgslen:
VÆLG i2l.country_code AS country_code, i2l.country_name AS country_name FRA ip2location i2l WHERE (i2l.ip_to>=INET_ATON('104.144.171.139') OG i2l.ip_from <=INET.10_4.13') ) LIMIT 1 OFFSET 0;
Og forespørgselsresultatet er:
+--------------+------------+| landekode | country_name |+--------------+----------------+| USA | USA |+---------------+---------------+
Brug af EXPLAIN
Forespørgslen er en skrivebeskyttet områdevalgsforespørgsel for at bestemme brugerens geografiske placeringsoplysninger (landekode og landenavn) for en IP-adresse på tabellen ip2location. Brug af EXPLAIN-sætningen kan hjælpe os med at forstå forespørgselsudførelsesplanen:
mysql> FORKLARING VÆLG i2l.country_code AS country_code, i2l.country_name AS country_name FRA ip2location i2l WHERE (i2l.ip_to>=INET_ATON('104.144.171.139') OG i2l.ip_4from. 171.139')) LIMIT 1 OFFSET 0;+----+------------------+-------+------------+ -------+---------------------------------------------+--- -----------+--------+------+------------------- ----------------------------------+| id | vælg_type | bord | skillevægge | type | mulige_nøgler | nøgle | key_len | ref | rækker | filtreret | Ekstra |+----+--------------+-------+------------+------- +---------------------------------------------+---------- ---+---------+------+-------------------- --------------------------+| 1 | ENKELT | i2l | NULL | rækkevidde | idx_ip_from,idx_ip_to,idx_ip_from_to | idx_ip_fra | 5 | NULL | 66043 | 50,00 | Brug af indeksbetingelse; Bruger hvor |+----+-------------+-------+------------+------ --+---------------------------------------------+--------- ----+---------+------+-------+---------- --------------------------+
Forespørgslen udføres med en rækkeviddescanning på tabellen ved hjælp af indeks idx_ip_from med 50 % potentielle rækker (filtreret).
Korrekt lagermotor
Ser på tabelstrukturen for ip2location:
mysql> VIS OPRET TABEL ip2location\G************************* 1. række ****** ********************* Tabel:ip2locationOpret tabel:CREATE TABLE `ip2location` ( `ip_from` int(10) unsigned DEFAULT NULL, `ip_to` int(10) unsigned DEFAULT NULL, `country_code` char(2) COLLATE utf8_bin DEFAULT NULL, `country_name` varchar(64) COLLATE utf8_bin DEFAULT NULL, KEY `idx_ip_from` (`ip_from`), KEY `idx_ip_to`` (`KEY_to`) idx_ip_from_to` (`ip_from`,`ip_to`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
Denne tabel er baseret på IP2location-databasen, og den bliver sjældent opdateret/skrevet, normalt kun på den første dag i kalendermåneden (anbefalet af leverandøren). Så en mulighed er at konvertere tabellen til MyISAM (MySQL) eller Aria (MariaDB) lagermotor med fast rækkeformat for at få bedre skrivebeskyttet ydeevne. Bemærk, at dette kun gælder, hvis du kører på MySQL eller MariaDB selvstændigt eller replikering. På Galera Cluster and Group Replication, skal du holde dig til InnoDB storage engine (medmindre du ved, hvad du laver).
Uanset hvad, for at konvertere tabellen fra InnoDB til MyISAM med fast rækkeformat, skal du blot køre følgende kommando:
ÆNDRINGSTABEL ip2location ENGINE=MyISAM ROW_FORMAT=FIXED;
I vores måling, med 1000 tilfældige IP-adresseopslagstest, forbedredes forespørgselsydeevnen omkring 20 % med MyISAM og fast rækkeformat:
- Gennemsnitlig tid (InnoDB):21,467823 ms
- Gennemsnitlig tid (MyISAM Fixed):17.175942 ms
- Forbedring:19,992157565301 %
Du kan forvente, at dette resultat vil være umiddelbart efter, at tabellen er ændret. Ingen ændring på det højere niveau (applikation/belastningsbalancer) er nødvendig.
Justering af forespørgslen
En anden måde er at inspicere forespørgselsplanen og bruge en mere effektiv tilgang til en bedre plan for udførelse af forespørgsler. Den samme forespørgsel kan også skrives ved hjælp af underforespørgsel som nedenfor:
VÆLG `country_code`, `country_name` FROM (SELECT `country_code`, `country_name`, `ip_from` FROM `ip2location` WHERE ip_to>=INET_ATON('104.144.171.139') LIMIT 1) SOM fristende WHERE ip_from <=INET_ATON('104.144.171.139');
Den indstillede forespørgsel har følgende plan for udførelse af forespørgsler:
mysql> FORKLARING VÆLG `landekode`,`landenavn` FRA (VÆLG `landekode`, `landenavn`, `ip_fra` FRA `ip2location` HVOR ip_to>=INET_ATON('104.144.171.139') LIMIT SOM fristende WHERE ip_from <=INET_ATON('104.144.171.139');+----+-------------+-------------+ ------------+--------+------------------+------------+ -------------+------------------------ ----------+| id | vælg_type | bord | skillevægge | type | mulige_nøgler | nøgle | key_len | ref | rækker | filtreret | Ekstra |+----+-------------+-----------------+ ---------------------------------------------- ---+-------+-----------+------------------------------+| 1 | PRIMÆR | | NULL | system | NULL | NULL | NULL | NULL | 1 | 100,00 | NULL || 2 | AFLEDT | ip2placering | NULL | rækkevidde | idx_ip_to | idx_ip_to | 5 | NULL | 66380 | 100,00 | Brug af indekstilstand |+----+-------------+--------------+----------- -+--------+----------------------------- -----+-------+-----------+----------------------------+
Ved at bruge underforespørgsel kan vi optimere forespørgslen ved at bruge en afledt tabel, der fokuserer på ét indeks. Forespørgslen skal kun returnere 1 post, hvor ip_to-værdien er større end eller lig med IP-adresseværdien. Dette gør det muligt for de potentielle rækker (filtreret) at nå 100 %, hvilket er det mest effektive. Kontroller derefter, at ip_from er mindre end eller lig med IP-adresseværdien. Hvis det er, så bør vi finde posten. Ellers findes IP-adressen ikke i ip2location-tabellen.
I vores måling forbedredes forespørgselsydeevnen omkring 99 % ved brug af en underforespørgsel:
- Gennemsnitlig tid (InnoDB + rækkeviddescanning):22,87112 ms
- Gennemsnitlig tid (InnoDB + underforespørgsel):0,14744 ms
- Forbedring:99,355344207017 %
Med ovenstående optimering kan vi se en forespørgselsudførelsestid på under millisekunder af denne type forespørgsel, hvilket er en massiv forbedring i betragtning af, at den tidligere gennemsnitlige tid er 22 ms. Vi er dog nødt til at foretage nogle ændringer af det højere niveau (applikation/belastningsbalancer) for at drage fordel af denne justerede forespørgsel.
Patching eller forespørgselsomskrivning
Patch dine applikationer for at bruge den indstillede forespørgsel, eller omskriv outlier-forespørgslen, før den når databaseserveren. Vi kan opnå dette ved at bruge en MySQL load balancer som ProxySQL (forespørgselsregler) eller MariaDB MaxScale (statement omskrivningsfilter) eller ved at bruge MySQL Query Rewriter plugin. I det følgende eksempel bruger vi ProxySQL foran vores databaseklynge, og vi kan simpelthen oprette en regel for at omskrive den langsommere forespørgsel til den hurtigere, for eksempel:
Gem forespørgselsreglen og overvåg siden Forespørgselsudfald i ClusterControl. Denne rettelse vil naturligvis fjerne afvigende forespørgsler fra listen, efter at forespørgselsreglen er aktiveret.
Konklusion
Forespørgsels-outliers er et proaktivt forespørgselsovervågningsværktøj, der kan hjælpe os med at forstå og løse ydeevneproblemet, før det er ved at komme ud af kontrol. Efterhånden som din applikation vokser og bliver mere krævende, kan dette værktøj hjælpe dig med at opretholde en anstændig databaseydeevne undervejs.