Bästa svaret
Även om både sammanfogningar och underfrågor har sin plats i SQL-uttalanden, försöker jag personligen alltid skriva mina frågor med hjälp av kopplingar uteslutande . Under tiden introducerar jag bara en underfråga när jag inte kan hämta de data jag vill ha utan en.
Anledningen är att anslutningar tenderar att köras snabbare. I själva verket skulle jag gå så långt som att säga att sökningstiden för förfrågan med hjälp av föreningar nästan alltid kommer att vara snabbare än för en underfråga.
Anledningen är att föreningar minskar beräkningsbördan på databas genom att ersätta flera frågor med en anslutningsfråga. Detta utnyttjar i sin tur bättre databasens förmåga att söka igenom, filtrera och sortera poster.
Naturligtvis, när du lägger till fler kopplingar till en fråga, måste databasservern göra mer arbete, vilket översätter för att sakta in datahämtningstiderna.
Även om föreningar är nödvändiga för att hämta data från en normaliserad databas är det viktigt att föreningar skrivs korrekt, eftersom felaktiga föreningar kan leda till allvarlig försämring av prestanda och felaktiga frågeresultat.
I vissa fall kan underfrågor ersätta komplexa sammanfogningar och förbund med endast en minimal negativ effekt på prestanda.
Exempel på underfrågor
Ibland kan du inte komma runt med en underfråga. Här är några exempel som använder Sakila Sample Database för MySQL och min Navicat databasutveckling och adminklient.
Exempel # 1: Använda en sammanlagd funktion som en del av en JOIN-klausul
För det mesta sammanfogas tabeller i ett gemensamt fält. Det är faktiskt inte ovanligt att det gemensamma fältet också delar samma namn för att visa att det är samma data. I följande fråga kopplas dock kundtabellen till den senaste (MAX) create\_date så att sökresultaten är för den kund som registrerade sig senast.
En underfråga används eftersom du inte kan använda aggregerade funktioner som en del av en WHERE-klausul. Denna geniala lösning kringgår den begränsningen!
Exempel # 2:
I denna fråga används en underfråga för att hämta en mellanliggande resultatuppsättning så att vi kan tillämpa AVG () -funktionen på ANTAL hyrda filmer. Det här är vad jag kallar en dubbel aggregering eftersom vi använder en aggregering (AVG) för resultatet av en annan (COUNT).
Den här frågan är ganska snabb – tar bara 0,044 sekunder – eftersom den inre frågan återvänder ett enda värde. Vanligtvis är de långsammaste frågorna de som kräver fullständiga tabellskanningar.
Hoppas det svarar på din fråga.
Hälsningar!
Adam
Svar
Vanligtvis bör du skriva frågor för att vara så tydliga som möjligt och lämna optimeringen till RDBMS frågeprocessor och DBA, om du har en som är ansvarig för att ställa in den fysiska designen. borde resultera i tillräckligt bra prestanda i de flesta fall, men det finns undantag. Ibland har en RDBMS sökfrågeoptimerare blinda fläckar eller dåliga fall. en optimerare är det mycket mer troligt att det finns underfrågor. Det beror på att anslutning är en grundläggande funktion i språket som alla användare använder, medan många användare inte använder underfrågor alls. Jag fann att konvertera en app från Sybase till SQL Server var jag tvungen att skriva om många underfrågor som sammanfogningar på grund av fel i Microsoft hantering av underfrågor – om än i ett mycket specifikt fall (där underfrågan där klausulen innehöll en bunden parameter). Det är inte förvånande att SQL Server hade buggar i underfrågor eftersom så många av dess kunder använder SQL Server med Microsofts grafiska frågeditorer som naturligt producerar sammanfogningar men inte underfrågor.
Jag rekommenderar vanligtvis inte för tidig optimering, men jag kommer att göra ett undantag här. Om din applikation måste vara bärbar över flera databasplattformar, skulle jag föredra att gå med underfrågor i de flesta fall eftersom du är mer benägna att stöta på buggar eller dåliga optimeringsval med underfrågor. applikationen behöver inte vara bärbar, skriv frågan på det som verkar vara det mest naturliga sättet och om det inte finns något problem – vilket kommer att vara för det mesta – bra. Om det finns ett problem, skriv om frågan annorlunda för att se om det hjälper. Och om du har en DBA, kontakta honom om eventuella prestationsproblem du har.