Delen via


Gegevenspagina's lezen in de database-engine

van toepassing op:SQL ServerAzure SQL Managed Instance

De I/O van een exemplaar van de SQL Server Database Engine bevat logische en fysieke leesbewerkingen. Een logische leesbewerking vindt plaats telkens wanneer de database-engine een pagina aanvraagt vanuit de buffercache, ook wel de buffergroep genoemd. Als de pagina zich momenteel niet in de buffercache bevindt, kopieert een fysieke leesbewerking eerst de pagina van de schijf naar de cache.

De leesaanvragen die worden gegenereerd door een exemplaar van de database-engine, worden beheerd door de relationele engine en geoptimaliseerd door de opslagengine. De relationele engine bepaalt de meest effectieve toegangsmethode (zoals een tabelscan, een indexscan of een gesleutelde leesopdracht). De toegangsmethoden en bufferbeheeronderdelen van de opslagengine bepalen het algemene patroon van leesbewerkingen die moeten worden uitgevoerd en optimaliseren de leesbewerkingen die nodig zijn om de toegangsmethode te implementeren. De thread die de batch uitvoert, plant de leesbewerkingen.

Vooruit lezen

De database-engine ondersteunt een mechanisme voor prestatieoptimalisatie, de zogenaamde read-ahead. Vooruit lezen verwacht de gegevens en indexpagina's die nodig zijn om te voldoen aan een queryuitvoeringsplan en brengt de pagina's in de buffercache voordat ze door de query worden gebruikt. Met dit proces kunnen berekeningen en I/O elkaar overlappen en profiteren van zowel de CPU als de schijf.

Met het mechanisme voor lezen kan de database-engine maximaal 64 aaneengesloten pagina's (512 kB) uit één bestand lezen. De leesbewerking wordt uitgevoerd als één spreidingsverzamelbewerking voor het juiste aantal (waarschijnlijk niet-aaneengesloten) buffers in de buffercache. Als een van de pagina's in het bereik al aanwezig is in de buffercache, wordt de bijbehorende pagina uit de leesbewerking verwijderd wanneer de leesbewerking is voltooid. Het bereik van pagina's kan ook van beide uiteinden worden 'ingekort' als de bijbehorende pagina's al aanwezig zijn in de cache.

Er zijn twee soorten read-ahead: één voor gegevenspagina's en één voor indexpagina's.

Gegevenspagina's lezen

Tabelscans die door de database-engine worden gebruikt om gegevenspagina's te lezen, zijn efficiënt. De pagina's voor indextoewijzing (IAM) in een SQL Server-database vermelden de extents die worden gebruikt door een tabel of index. De opslagengine kan de IAM lezen om een gesorteerde lijst te maken met de schijfadressen die moeten worden gelezen. Hierdoor kan de opslagengine het I/Os optimaliseren als grote opeenvolgende leesbewerkingen die op volgorde worden uitgevoerd, op basis van hun locatie op de schijf. Voor meer informatie over IAM-pagina's, zie Ruimte beheren die wordt gebruikt door objecten.

Indexpagina's lezen

De opslagengine leest de indexpagina's in sleutelvolgorde. Deze illustratie toont bijvoorbeeld een vereenvoudigde weergave van een verzameling bladpagina's met een set sleutels en het tussenliggende indexknooppunt dat de bladpagina's aan elkaar verbindt. Zie Geclusterde en niet-geclusterde indexen voor meer informatie over de structuur van pagina's in een index.

Diagram van het lezen van pagina's uit de buffercache.

De opslagengine gebruikt de informatie op de tussenliggende indexpagina boven het bladniveau om seriële leesbewerkingen te plannen voor de pagina's die de sleutels bevatten. Als er een aanvraag wordt gedaan voor alle sleutels van ABC naar DEF, leest de opslagengine eerst de indexpagina boven de bladpagina. Het leest echter niet alleen elke gegevenspagina op volgorde van pagina 504 naar pagina 556 (de laatste pagina met sleutels in het opgegeven bereik). In plaats daarvan scant de opslagengine de tussenliggende indexpagina en bouwt een lijst met de bladpagina's die moeten worden gelezen. De opslagengine plant vervolgens alle leesbewerkingen in sleutelvolgorde. De opslagengine herkent ook dat pagina's 504/505 en 527/528 aaneengesloten zijn en één spreidingsleesbewerking uitvoeren om de aangrenzende pagina's in één bewerking op te halen. Wanneer er veel pagina's moeten worden opgehaald in een seriële bewerking, plant de opslagengine een blok leesbewerkingen tegelijk. Wanneer een subset van deze leesbewerkingen is voltooid, plant de opslagengine een gelijk aantal nieuwe leesbewerkingen totdat alle vereiste leesbewerkingen zijn gepland.

De opslagengine maakt gebruik van prefetching om basistabelzoekacties van niet-geclusterde indexen te versnellen. De bladrijen van een niet-geclusterde index bevatten aanwijzers naar de gegevensrijen die elke specifieke sleutelwaarde bevatten. Terwijl de opslagengine de bladpagina's van de niet-geclusterde index doorneemt, begint hij ook met het plannen van asynchrone leesbewerkingen voor de gegevensrijen waarvan de pointers al zijn opgehaald. Hierdoor kan de opslagengine gegevensrijen ophalen uit de onderliggende tabel voordat de scan van de niet-geclusterde index wordt voltooid. Prefetching wordt gebruikt, ongeacht of de tabel een geclusterde index heeft. SQL Server Enterprise Edition maakt gebruik van meer prefetching dan andere edities van SQL Server, zodat er meer pagina's vooruit kunnen worden gelezen. Het niveau van prefetching kan in geen enkele editie worden geconfigureerd. Zie Geclusterde en niet-geclusterde indexen voor meer informatie over niet-geclusterde indexen.

Geavanceerd scannen

In SQL Server Enterprise Edition biedt de geavanceerde scanfunctie de mogelijkheid om volledige tabelscans door meerdere taken te laten delen. Als voor het uitvoeringsplan van een Transact-SQL-instructie een scan van de gegevenspagina's in een tabel is vereist en de database-engine detecteert dat de tabel al wordt gescand op een ander uitvoeringsplan, voegt de database-engine de tweede scan toe aan de eerste, op de huidige locatie van de tweede scan. De database-engine leest elke pagina één keer en geeft de rijen van elke pagina door aan beide uitvoeringsplannen. Dit gaat door tot het einde van de tabel is bereikt.

Op dat moment heeft het eerste uitvoeringsplan de volledige resultaten van een scan. Het tweede uitvoeringsplan moet echter nog steeds de gegevenspagina's ophalen die zijn gelezen voordat deze is toegevoegd aan de scan die wordt uitgevoerd. De scan voor het tweede uitvoeringsplan loopt vervolgens terug naar de eerste gegevenspagina van de tabel en scant door naar de locatie waar deze is toegevoegd aan de eerste scan. Een willekeurig aantal scans kan als volgt worden gecombineerd. De database-engine blijft de gegevenspagina's doorlopen totdat alle scans zijn voltooid. Dit mechanisme wordt ook wel 'merry-go-round scanning' genoemd en laat zien waarom de volgorde van de resultaten die worden geretourneerd door een SELECT instructie niet kan worden gegarandeerd zonder een ORDER BY component.

Stel dat u een tabel met 500.000 pagina's hebt. UserA voert een Transact-SQL instructie uit waarvoor een scan van de tabel is vereist. Wanneer deze scan 100.000 pagina's heeft verwerkt, UserB voert u een andere Transact-SQL instructie uit waarmee dezelfde tabel wordt gescand. De database-engine plant één set leesaanvragen voor pagina's na 100.001 en geeft de rijen van elke pagina weer door aan beide scans. Wanneer de scan de 200.000e pagina bereikt, UserC voert u een andere Transact-SQL instructie uit waarmee dezelfde tabel wordt gescand. Vanaf pagina 200.001 geeft de database-engine de rijen van elke pagina door die wordt teruggelezen naar alle drie de scans. Nadat de 500.000e rij is gelezen, is de scan voor UserA voltooid, en worden de scans voor UserB en UserC teruggezet en beginnen ze de pagina's te lezen vanaf pagina 1. Wanneer de database-engine pagina 100.000 bereikt, wordt de scan voor UserB voltooid. De scan gaat vervolgens alleen door totdat het pagina 200.000 bereikt. Op dit moment zijn alle scans voltooid.

Zonder geavanceerd scannen zou elke gebruiker moeten concurreren voor bufferruimte en conflicten tussen schijfarmen veroorzaken. Dezelfde pagina's worden dan één keer gelezen voor elke gebruiker in plaats van één keer gelezen en door meerdere gebruikers gedeeld, waardoor de prestaties vertraging oplopen en belasting van middelen plaatsvindt.