Experts weten hoe ze prestatie-efficiënte queries moeten schrijven. Hoewel ervaring wijsheid rijpt, zijn er bepaalde dingen die men in ieder geval moet begrijpen om mee te beginnen. U moet bijvoorbeeld de belangrijkste overwegingen bij het ontwerpen van query's begrijpen; hoe een query intern presteert, waar deze faalt, optimalisatiepatronen, enz. In dit artikel geef ik een paar optimalisatiepunten om over na te denken bij het ontwerpen van een query in MySQL.
Waarom zijn sommige zoekopdrachten traag?
Een veelvoorkomend probleem bij SQL-query's is dat er meer gegevens worden opgehaald dan daadwerkelijk nodig is. Natuurlijk zijn er vragen die veel gegevens doorzoeken en we kunnen er niet veel aan doen, maar ze komen niet vaak voor. In de meeste gevallen is het een slecht queryontwerp dat leidt tot slechte queryprestaties. Na elk ontwerp van een query moet u introspecteren op een aantal aspecten, zoals wat er kan gebeuren nadat de query is geactiveerd:
- Heeft de SQL-query toegang tot te veel kolommen of rijen?
- Zal de MySQL-server te veel rijen analyseren om het gewenste resultaat te verkrijgen?
Er zijn query's die ervoor zorgen dat de MySQL-server analyseert op te veel gegevens, maar deze tijdens het zeven weggooit. Dit is extra werk voor de server in termen van vele aspecten, zoals netwerkoverhead, te veel geheugengebruik of te veel CPU-brongebruik op de server. Het gevolg is trage prestaties.
Er zijn situaties waarin u tijdens het ontwerp misschien niet veel kunt helpen, maar er is een situatie waarin als u voorzichtig bent en de gevolgen en introspectie inschat, een slechte vraag op zijn minst goed, zo niet beter kan worden gemaakt.
Typische fouten en hun oplossingen
Er zijn nogal wat veelvoorkomende fouten die vaak worden gemaakt tijdens het schrijven van een query. Hier zijn er een paar. Je kunt er nog een paar vinden op dezelfde lijn. Hier zijn redenen voor trage queryprestaties met mogelijke oplossingen.
Te veel rijen
De fout wordt vaak gemaakt door een query te schrijven die gegevens ophaalt en ervan uit te gaan dat MySQL resultaten op aanvraag zal opleveren, terwijl de hoeveelheid verwerking die nodig is om de volledige resultatenset te retourneren, over het hoofd wordt gezien. Stel dat er een SELECT-instructie wordt geactiveerd om 100 productdetails voor een e-commercesite op te halen, terwijl slechts 10 daarvan eerst moeten worden weergegeven. Je zou kunnen denken dat MySQL slechts 10 rijen ophaalt en stopt met het uitvoeren van de query. Maar nee. Wat MySQL doet, is de volledige resultatenset genereren en de klant voeden. De clientbibliotheek ontvangt de complete set en gooit het meeste weg en behoudt er slechts 10 waarvan het zoekt. Dit verspilt duidelijk veel bronnen.
In een dergelijke situatie kunt u echter een oplossing bieden door de LIMIT-clausule bij de vraag te gebruiken.
SELECT col1, col2,... FROM table_name LIMIT [offset,] count;
De LIMIT-clausule accepteert een of twee parameters. De eerste specificeert de offset en de tweede specificeert het aantal. Als er slechts één parameter is opgegeven, geeft dit het aantal rijen aan vanaf het begin van de resultatenset.
Als u bijvoorbeeld 10 rijen uit de tabel wilt selecteren, kunt u schrijven:
SELECT e.emp_name, e.phone, e.email FROM employee e LIMIT 10;
En voor het selecteren van de volgende 10 rijen, beginnend bij 11 records, kunt u schrijven:
SELECT e.emp_name, e.phone, e.email FROM employee e LIMIT 10, 10;
Te veel kolommen
Kijk altijd met argwaan naar de vraag:SELECT *. Deze query retourneert alle kolommen en u hebt er waarschijnlijk maar enkele nodig. Het grootste nadeel van het ophalen van alle kolommen is dat het optimalisatie voorkomt door het gebruik van indexen te belemmeren, teveel I/O-, geheugen- en CPU-bronnen van de server vraagt.
Begrijp dat zo'n universele zoekopdracht waarbij alle kolommen worden opgehaald, verspillend kan zijn. Sommigen zeggen dat ze nuttig zijn omdat het de ontwikkelaar in staat stelt hetzelfde stukje code op meer dan één plaats te gebruiken. Dat is prima als de kosten die ermee gemoeid zijn binnen de overweging beperkt zijn. Soms helpt het cachen van opgehaalde gegevens in deze context. Maar wees voorzichtig, het benutten van prestaties is een gestroomlijnde klus en voor zulke luxe is misschien geen plaats voor prestaties.
De vuistregel is om dergelijke universele zoekopdrachten te vermijden of het aantal opgehaalde kolommen tot een minimum te beperken.
Te veel data-analyse
Query's retourneren het gewenste resultaat, dat is prima, maar soms zijn deze query's zo geschreven dat tijdens de verwerking te veel gegevens moeten worden onderzocht voordat resultaten worden gegenereerd. Daarom moet u in MySQL meten volgens de volgende kostenstatistieken:
- Uitvoeringstijd
- Rijen onderzocht
- Kolommen onderzocht
U kunt op basis van deze statistieken een ruwe schatting van de kosten van zoekopdrachten krijgen. Deze weerspiegelen de hoeveelheid gegevenstoegang door MySQL intern om de query te verwerken en hoe snel de query wordt uitgevoerd. Aangezien deze metrische gegevens worden vastgelegd in het trage querylogboek, is het een goed idee om query's te onderzoeken en te vinden die te veel gegevens analyseren om het resultaat te retourneren. MySQL-database registreert alle query's die een bepaalde uitvoeringstijd overschrijden in een langzame querylog. Dit is een ideale plek om naar langzame zoekopdrachten te zoeken en erachter te komen hoe vaak ze traag zijn.
Een langzame querylog bevindt zich meestal op /var/log/mysql/mysql-slow.log
Houd er rekening mee dat u het loggen van langzame query's mogelijk moet instellen en inschakelen in mysqld.cnf configuratiebestand als volgt.
#slow_query_log = 1 #slow_query_log_file = /var/log/mysql/mysql-slow.log #long_query_time = 2
Voorafgaand aan en met MySQL 5 waren er ernstige beperkingen, vooral het ontbreken van ondersteuning voor fijnmazige logging. Enige uitstel was het gebruik van patches die logging mogelijk maakten. De functie maakte echter deel uit van de MySQL 5.1 en latere servers als onderdeel van de kernfunctie.
Query's die te veel tijd in beslag nemen, betekenen niet noodzakelijk dat het slechte query's zijn. Het trage querylogboek biedt eenvoudig de mogelijkheid om de queryprestaties te onderzoeken en zo mogelijk te verbeteren.
Herstructurering van zoekopdrachten
Aangezien u de mogelijkheid heeft om problematische vragen te herstructureren, moet uw primaire doel zijn om een alternatieve oplossing te vinden om het gewenste effect te bereiken. U kunt de query omzetten in zijn equivalente vorm, rekening houdend met het interne effect in de MySQL-server tijdens de verwerking.
Een beslissing bij het ontwerpen van query's is of we de voorkeur moeten geven aan één complexe query in plaats van meerdere eenvoudige of omgekeerd. De conventionele benadering van databaseontwerp is om zoveel mogelijk werken te doen met minder query's. De reden is dat één grote/complexe query kosteneffectiever is in termen van het tot stand brengen van een databaseverbinding. Het voordeel van kostenreductie ten gunste van complexe query's is netwerkgebruik, queryverwerking/optimalisatie en resourcegebruik. Maar deze traditionele aanpak past niet goed bij MySQL. MySQL is ontworpen om snel verbinding te maken met de database en de verbinding te verbreken. Daarom lijkt het opzetten van een verbinding, het afvuren van veel eenvoudigere query's en het sluiten van de verbinding efficiënter. Het ophalen van gegevens via meer dan één eenvoudige query in plaats van één grote complexe is effectiever. Merk op dat hetzelfde idee mogelijk niet wordt toegepast met andere databases.
Conclusie
Dit zijn een paar snelle tips voor het optimaliseren van zoekopdrachten. Begrijp dat, met kennis van SQL-syntaxis, in staat zijn om een query te maken die het gewenste resultaat ophaalt, niet voldoende is als men streeft naar prestatie van de query. Het begrijpen van de gebeurtenissen onder de ogenschijnlijk eenvoudig ogende vragen is van vitaal belang bij het schrijven van een vraag die niet alleen ophaalt wat gewenst is, maar ook de kunst van optimalisatie doordrenkt vanaf waar het allemaal begint. De achter de schermen van de verwerking van zoekopdrachten geven een belangrijke aanwijzing om de prestaties van zoekopdrachten te begrijpen en deze kennis is een must voordat je je op het gebied van zoekopdrachtoptimalisatie begeeft.