sql >> Database >  >> RDS >> Database

Aantal rijen Lezen / Werkelijke rijen Lees waarschuwingen in Plan Explorer

De nieuwe eigenschap "Actual Rows Read" in uitvoeringsplannen (die in SQL Server Management Studio wordt weergegeven als "Number of Rows Read") was een welkome aanvulling op prestatietuners. Het is alsof je een nieuwe superkracht hebt, om de betekenis van het Seek-predikaat versus het resterende predikaat binnen een Seek-operator te kunnen zien. Ik vind dit geweldig, omdat het heel belangrijk kan zijn voor het doorzoeken.

Laten we eens kijken naar twee query's die ik tegen AdventureWorks2012 uitvoer. Ze zijn heel eenvoudig:de ene vermeldt mensen die John S worden genoemd, en de andere vermeldt mensen die J Smith worden genoemd. Zoals alle goede telefoonboeken hebben we een index op Achternaam, Voornaam.

select FirstName, LastName 
  from Person.Person
  where LastName like 'S%'
  and FirstName = 'John'; 
 
select FirstName, LastName 
  from Person.Person 
  where LastName = 'Smith' 
  and FirstName like 'J%';

Voor het geval je nieuwsgierig bent, ik krijg 2 rijen terug van de eerste en 14 rijen terug van de tweede. Ik ben eigenlijk niet zo geïnteresseerd in de resultaten, ik ben geïnteresseerd in de uitvoeringsplannen.

Laten we eens kijken wat er aan de hand is. Ik opende een ouder exemplaar van SQL Sentry Plan Explorer en open mijn plannen naast elkaar. Overigens - ik had beide query's samen uitgevoerd en dus stonden beide plannen in hetzelfde .sqlplan-bestand. Maar ik zou hetzelfde bestand twee keer in PE kunnen openen en ze met plezier naast elkaar in tabbladen kunnen plaatsen.

Super goed. Ze zien er hetzelfde uit! Ik kan zien dat de zoekfunctie aan de linkerkant twee rijen produceert in plaats van veertien – dit is duidelijk de betere zoekopdracht.

Maar met een groter venster zou ik meer informatie hebben gezien, en het is een geluk dat ik de twee zoekopdrachten in dezelfde batch had uitgevoerd.

U kunt zien dat de tweede zoekopdracht, die 14 rijen opleverde in plaats van 2 rijen, naar schatting 80% van de kosten op zich nam! Als ik de query's afzonderlijk zou uitvoeren, zou elk me 100% laten zien.

Laten we nu vergelijken met de nieuwste release van Plan Explorer.

Wat me meteen opvalt is de waarschuwing. Laten we eens wat dichterbij kijken.

De waarschuwing zegt:"Bewerking veroorzaakte resterende IO. Het werkelijke aantal gelezen rijen was 2.130, maar het aantal geretourneerde rijen was 2. En ja hoor, verderop zien we "Actual Rows Read" met 2130 en Actual Rows op 2.

Wauw! Om die rijen te vinden, moesten we door 2130 kijken?

Zie je, de manier waarop de Seek werkt, is om te beginnen door na te denken over het Seek-predikaat. Dat is degene die goed gebruik maakt van de index en die ervoor zorgt dat de operatie een Seek is. Zonder een zoekpredikaat wordt de bewerking een scan. Als dit Seek-predikaat gegarandeerd maximaal één rij is (zoals wanneer het een gelijkheidsoperator op een unieke index heeft), dan hebben we een Singleton-zoekopdracht. Anders hebben we een bereikscan en dit bereik kan een voorvoegsel, een begin en een einde hebben (maar niet noodzakelijk zowel een begin als een einde). Dit definieert de rijen in de tabel waarin we geïnteresseerd zijn voor de Seek.

Maar 'geïnteresseerd in' betekent niet noodzakelijkerwijs 'teruggekeerd', omdat we misschien meer werk te doen hebben. Dat werk wordt beschreven in het andere Predikaat, dat vaak bekend staat als het Restpredikaat.

Nu dat Residual Predicate misschien wel het meeste werk doet. Het is er zeker - het filtert dingen van 2.130 rijen naar slechts 2.

De Range Scan begint in de index bij “John S”. We weten dat als er een "John S" is, dit de eerste rij moet zijn die het hele ding kan bevredigen. "Ian S" kan dat niet. Dus we kunnen op dat moment in de index zoeken om onze Range Scan te starten. Als we naar de Plan XML kijken, kunnen we dit expliciet zien.

Merk op dat we geen voorvoegsel hebben. Dat geldt als je een gelijkheid hebt in de eerste kolom binnen de index. We hebben alleen StartRange en EndRange. Het begin van het bereik is "Groter dan of gelijk aan" (GE) ScanType, bij de waarde "S, John" (de kolomverwijzingen buiten het scherm zijn Achternaam, Voornaam), en het einde van het bereik is "Kleiner dan" ( LT) de waarde T. Wanneer de scan T bereikt, is het klaar. Niets meer te doen. De Seek heeft nu zijn Range Scan voltooid. En in dit geval levert het 2.130 rijen op!

Behalve dat het niet echt 2.130 rijen retourneert, leest het gewoon 2.130 rijen. Namen als Barry Sai en Ken Sánchez worden gelezen, maar alleen de namen die voldoen aan de volgende controle worden geretourneerd - het Residual Predikaat dat ervoor zorgt dat de FirstName John is.

Het item Actual Rows Read in de eigenschappen van de Index Seek-operator toont ons deze waarde van 2.130. En hoewel het zichtbaar is in eerdere releases van Plan Explorer, krijgen we er geen waarschuwing over. Dat is relatief nieuw.

Onze tweede zoekopdracht (op zoek naar J Smith) is veel leuker, en er is een reden waarom het naar schatting meer dan 4 keer goedkoper was.

Hier kennen we de Achternaam precies (Smith), en de Range Scan staat op de Voornaam (J%).

Hier komt het voorvoegsel om de hoek kijken.

We zien dat ons voorvoegsel een gelijkheidsoperator (=, ScanType=”EQ”) is, en dat LastName Smith moet zijn. We hebben het begin of het einde van het bereik nog niet eens overwogen, maar het voorvoegsel vertelt ons dat het bereik is opgenomen in het gedeelte van de index waar LastName Smith is. Nu kunnen we de rijen>=J en

Er is hier nog steeds een residuaal predikaat, maar dit is alleen om ervoor te zorgen dat "LIKE J%" daadwerkelijk wordt getest. Hoewel het ons intuïtief lijkt dat "LIKE J%" precies gelijk is aan ">=J en

Vóór Service Pack 3 van SQL Server 2012 hadden we deze eigenschap niet, en om een ​​idee te krijgen van het verschil tussen de werkelijke rijen lezen en de werkelijke rijen, moesten we traceringsvlag 9130 gebruiken. Dit zijn die twee plannen met die TF aan:

U kunt zien dat er deze keer geen waarschuwing is, omdat de zoekoperator alle 2130 rijen retourneert. Ik denk dat als je een versie van SQL Server gebruikt die deze Actual Rows Read ondersteunt, je moet stoppen met het gebruik van de traceringsvlag 9130 in je onderzoeken en in plaats daarvan naar de waarschuwingen in Plan Explorer moet gaan kijken. Maar begrijp vooral hoe uw operators hun werk doen, want dan kunt u interpreteren of u tevreden bent met het plan of dat u actie moet ondernemen.

In een ander bericht laat ik je een situatie zien waarin je de werkelijke rijen gelezen liever hoger ziet dan de werkelijke rijen.

@rob_farley


  1. gegevens van de ene tabel naar de andere verplaatsen, postgresql-editie

  2. Vernieuw een gerealiseerde weergave automatisch met behulp van een regel of melding

  3. elimineer dubbele matrixwaarden in postgre

  4. Doe mee op dinsdag 9 april voor het laatste Microsoft Access-nieuws