sql >> Databasteknik >  >> RDS >> Mysql

Fråga prestandaoptimering i MySQL

Experter vet hur man skriver prestandaeffektiva frågor. Även om erfarenhet mognar visdom, finns det vissa saker som man måste förstå åtminstone till att börja med. Till exempel måste du förstå viktiga aspekter av frågedesign; hur en fråga fungerar internt, var den misslyckas, optimeringsmönster etc. I den här artikeln kommer jag att ge några optimeringspunkter att fundera över när jag designar en fråga i MySQL.

Varför är vissa frågor långsamma?

Ett vanligt problem med SQL-frågor är att mer data hämtas än vad som faktiskt behövs. Naturligtvis finns det frågor som sållar igenom mycket data och vi kan inte göra så mycket åt dem, men de är inte vanliga. I de flesta fall är det dålig frågedesign som leder till dålig frågeprestanda. Efter varje frågedesign måste du introspektera på några aspekter som vad som kan hända efter att frågan har avfyrats:

  1. Kommer SQL-frågan åtkomst till för många kolumner eller rader?
  2. Kommer MySQL-servern att analysera för många rader för att hämta det önskade resultatet?

Det finns frågor som gör att MySQL-servern analyserar för mycket data men kastar dem när den sållar. Detta är ett extra arbete för servern när det gäller många aspekter som nätverksoverhead, för mycket minnesförbrukning eller för mycket CPU-resursanvändning på servern. Konsekvensen är långsam prestanda.

Det finns situationer där du kanske inte kan hjälpa till mycket under designen, men det finns en situation där om du är försiktig och uppskattar konsekvensen och introspektivt, så kan en dålig fråga åtminstone göras bra om inte bättre.

Typiska misstag och deras lösningar

Det finns en hel del vanliga misstag som ofta görs när du skriver en fråga. Här är några av dem. Du kan hitta några fler som tänker på samma linje. Här är skälen till långsam frågeprestanda med möjliga lösningar.

För många rader

Misstaget görs ofta att skriva en fråga som hämtar data och anta att MySQL kommer att ge resultat på begäran samtidigt som man förbiser mängden bearbetning som krävs för att returnera hela resultatuppsättningen. Anta att en SELECT-sats avfyras för att hämta 100 produktdetaljer för en e-handelssida när endast 10 av dem faktiskt behöver visas först. Du kanske tror att MySQL bara hämtar 10 rader och slutar köra frågan. Men nej. Vad MySQL gör är att generera hela resultatuppsättningen och mata klienten. Klientbiblioteket tar emot hela uppsättningen och kasserar det mesta och behåller endast 10 av dem som det söker. Detta slösar helt klart mycket resurser.

Men i en sådan situation kan du tillhandahålla en lösning genom att använda LIMIT-satsen med frågan.

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

LIMIT-satsen accepterar en eller två parametrar. Den första anger förskjutningen och den andra anger antalet. Om endast en parameter anges anger den antalet rader från början av resultatuppsättningen.

För att till exempel välja 10 rader från tabellen kan du skriva:

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

Och för att välja de nästa 10 raderna, med start från 11 post, kan du skriva:

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

För många kolumner

Titta alltid på frågan:SELECT * med misstänksamhet. Den här frågan returnerar alla kolumner och du behöver förmodligen bara några av dem. Den största nackdelen med att hämta alla kolumner är att det förhindrar optimering genom att hindra användningen av index, kräver för mycket I/O, minne och CPU-resurser från servern.

Förstå att en sådan universell fråga som hämtar alla kolumner kan vara slösaktig. Vissa säger att de är användbara eftersom det låter utvecklare använda samma kodbit på mer än ett ställe. Det är bra om kostnaden är begränsad i övervägande. Ibland hjälper cachelagring av hämtad data i detta sammanhang. Men var dock försiktig, att utnyttja prestanda är ett elegant jobb och sådan lyx kanske inte har en plats för prestanda.

Tumregeln är att undvika sådana universella förfrågningar eller hålla ett antal kolumner hämtade så lite som möjligt.

För mycket dataanalys

Frågor returnerar önskat resultat, det är bra, men ibland skrivs dessa frågor på ett sådant sätt att det under bearbetningen kräver att man undersöker för mycket data innan resultat genereras. Därför måste du i MySQL mäta enligt följande kostnadsmått:

  • Utförandetid
  • Rader granskade
  • Kolumner granskade

Du kan få en grov uppskattning av frågekostnaden från dessa mätvärden. Dessa återspeglar mängden dataåtkomst av MySQL internt för att bearbeta frågan och hur snabbt frågan går. Eftersom dessa mätvärden loggas i den långsamma frågeloggen är det en bra idé att undersöka och hitta frågor som analyserar för mycket data för att returnera resultatet. MySQL-databas registrerar alla frågor som överskrider en given mängd exekveringstid i långsam frågelogg. Detta är en idealisk plats för att leta efter långsamma frågor och ta reda på hur ofta de är långsamma.

En långsam frågelogg finns vanligtvis på /var/log/mysql/mysql-slow.log

Observera att man kanske måste ställa in och aktivera loggning av långsamma frågor i mysqld.cnf konfigurationsfil enligt följande.

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

Före och med MySQL 5 fanns det allvarliga begränsningar, särskilt som saknade stöd för finkornig loggning. Enda respit var att använda patchar som möjliggjorde loggning. Funktionen har dock varit en del av MySQL 5.1 och senare servrar som en del av dess kärnfunktion.

Frågor som tar för mycket tid att köra betyder inte nödvändigtvis att de är dåliga frågor. Den långsamma frågeloggen ger helt enkelt möjlighet att undersöka frågeprestanda och förbättra den så mycket som möjligt.

Omstruktureringsfrågor

Eftersom du har möjlighet att omstrukturera problematiska frågor bör ditt primära mål vara att hitta en alternativ lösning för att uppnå den effekt vi vill ha. Du kan omvandla frågan till dess motsvarande form med tanke på den interna effekten i MySQL-servern under bearbetning.

Ett beslut i frågedesign är om vi ska favorisera en komplex fråga istället för flera enkla eller vice versa. Den konventionella metoden för databasdesign är att göra så många arbeten som möjligt med färre frågor. Anledningen är att en stor/komplex fråga är mer kostnadseffektiv när det gäller att upprätta databasanslutning. Fördelen med kostnadsreduktion till förmån för komplexa frågor är nätverksanvändning, frågebehandling/optimering och resursutnyttjande. Men detta traditionella tillvägagångssätt passar inte bra med MySQL. MySQL är designat för att snabbt hantera databasanslutning och frånkoppling. Därför verkar det vara mer effektivt att upprätta anslutning, skicka många enklare frågor och stänga anslutningen. Att hämta data genom mer än en enkel fråga istället för en stor komplex är mer effektivt. Observera att samma idé kanske inte kan tillämpas med andra databaser.

Slutsats

Det här är några snabba tips för att söka efter optimering. Förstå att, med kunskap om SQL-syntaxer, att kunna skapa en fråga som hämtar det önskade resultatet inte är tillräckligt om man siktar på frågeprestanda. Att förstå vad som händer under de till synes enkla frågorna är avgörande för att skriva en som inte bara hämtar det som önskas utan genomsyrar konsten att optimera precis där allt börjar. Det som händer bakom frågebehandlingen ger en viktig ledtråd för att förstå frågeprestanda, och denna kunskap är ett måste innan man tar sig in i frågeoptimeringens område.


  1. Hur kan jag skicka någon http-förfrågan från postgresql-funktion eller trigger

  2. De bästa verktygen med öppen källkod för MySQL- och MariaDB-migreringar

  3. SET NULL:Ange en sträng som ska returneras när ett nollvärde förekommer i SQLcl / SQL*Plus

  4. Kontrollera om tabellen finns och om den inte finns, skapa den i SQL Server 2008