sql >> Databasteknik >  >> RDS >> Mysql

Hur man optimerar frågor i en databas - Grunderna

Du måste leta upp för alla villkor och för varje anslutning ... på villkor. De två fungerar likadant.

Anta att vi skriver

select name
from customer
where customerid=37;

På något sätt måste DBMS hitta posten eller posterna med kundid=37. Om det inte finns något index är det enda sättet att göra detta att läsa varje post i tabellen som jämför kund-id med 37. Även när den hittar ett, har den inget sätt att veta att det bara finns en, så den måste fortsätta leta efter andra.

Om du skapar ett index på kund-id, har DBMS sätt att söka i indexet mycket snabbt. Det är inte en sekventiell sökning, utan, beroende på databasen, en binär sökning eller någon annan effektiv metod. Exakt hur spelar ingen roll, acceptera att det är mycket snabbare än sekventiellt. Indexet tar det sedan direkt till lämplig post eller lämpliga poster. Dessutom, om du anger att indexet är "unikt", så vet databasen att det bara kan finnas ett så att det inte slösar tid på att leta en sekund. (Och DBMS kommer att hindra dig från att lägga till en andra.)

Överväg nu den här frågan:

select name
from customer
where city='Albany' and state='NY';

Nu har vi två förutsättningar. Om du bara har ett index på ett av dessa fält, kommer DBMS att använda det indexet för att hitta en delmängd av posterna och sedan söka efter dem. Till exempel, om du har ett index på tillstånd, kommer DBMS snabbt att hitta den första posten för NY, sedan söka efter city='Albany' i följd och sluta leta när den når den sista posten för NY.

Om du har ett index som inkluderar båda fälten, d.v.s. "skapa index på kund (delstat, stad)", så kan DBMS omedelbart zooma till rätt poster.

Om du har två separata index, ett på varje fält, kommer DBMS att ha olika regler som gäller för att avgöra vilket index som ska användas. Återigen, exakt hur detta görs beror på det specifika DBMS du använder, men i grund och botten försöker den hålla statistik över det totala antalet poster, antalet olika värden och fördelningen av värden. Sedan kommer den att söka i dessa poster sekventiellt efter de som uppfyller det andra villkoret. I det här fallet skulle DBMS förmodligen observera att det finns många fler städer än det finns stater, så genom att använda stadsindexet kan det snabbt zooma till "Albany"-posterna. Sedan kommer den att söka i dessa i sekventiell ordning och kontrollera tillståndet för var och en mot 'NY'. Om du har poster för Albany, Kalifornien, kommer dessa att hoppas över.

Varje anslutning kräver någon form av uppslag.

Säg att vi skriver

select customer.name
from transaction
join customer on transaction.customerid=customer.customerid
where transaction.transactiondate='2010-07-04' and customer.type='Q';

Nu måste DBMS bestämma vilken tabell som ska läsas först, välja lämpliga poster därifrån och sedan hitta de matchande posterna i den andra tabellen.

Om du hade ett index på transaction.transactiondate och customer.customerid, skulle den bästa planen troligen vara att hitta alla transaktioner med detta datum, och sedan för var och en av dessa hitta kunden med det matchande kund-id, och sedan verifiera att kunden har rätt typ.

Om du inte har ett index på customer.customerid, kan DBMS snabbt hitta transaktionen, men för varje transaktion måste den sekventiellt söka i kundtabellen och leta efter ett matchande kund-id. (Detta skulle sannolikt gå väldigt långsamt.)

Anta istället att de enda indexen du har är på transaktion.kund-id och kund.typ. Då skulle DBMS troligen använda en helt annan plan. Det skulle troligen skanna kundtabellen efter alla kunder med rätt typ, sedan för var och en av dessa hitta alla transaktioner för denna kund, och sekventiellt söka efter dem efter rätt datum.

Den viktigaste nyckeln till optimering är att ta reda på vilka index som verkligen kommer att hjälpa och skapa dessa index. Extra oanvända index är en börda för databasen eftersom det kräver arbete att underhålla dem, och om de aldrig används är det bortkastad ansträngning.

Du kan se vilka index som DBMS kommer att använda för en given fråga med kommandot EXPLAIN. Jag använder detta hela tiden för att avgöra om mina frågor optimeras väl eller om jag borde skapa ytterligare index. (Läs dokumentationen om detta kommando för en förklaring av dess utdata.)

Varning:Kom ihåg att jag sa att DBMS för statistik över antalet poster och antalet olika värden och så vidare i varje tabell. EXPLAIN kan ge dig en helt annan plan idag än den gav igår om data har ändrats. Till exempel, om du har en fråga som sammanfogar två tabeller och en av dessa tabeller är mycket liten medan den andra är stor, kommer den att vara partisk mot att läsa den lilla tabellen först och sedan hitta matchande poster i den stora tabellen. Att lägga till poster i en tabell kan ändra vilken som är större och därmed leda till att DBMS ändrar sin plan. Därför bör du försöka göra EXPLAINS mot en databas med realistiska data. Att köra mot en testdatabas med 5 poster i varje tabell är av mycket mindre värde än att köra mot en livedatabas.

Tja, det finns mycket mer att säga, men jag vill inte skriva en bok här.



  1. Hur man sorterar i SQL, ignorerar artiklar ('the, a', etc)

  2. MySQL bind-adress i en Docker-behållare

  3. Felsökning av SQL Server Always On Availability Groups

  4. Få resultat från MySQL med PDO