sql >> Database teknologi >  >> RDS >> Database

Top 3 tips, du skal vide for at skrive hurtigere SQL-visninger

Ven eller fjende? SQL Server synspunkter har været genstand for heftige debatter, da jeg i mit første år brugte SQL Server. De sagde, at det var dårligt, fordi det var langsomt. Men hvad med i dag?

Er du på samme båd, som jeg var for mange år siden? Så tag med mig på denne rejse for at opklare den virkelige vare om SQL-visninger, så du kan skrive dem hurtigst muligt.

SQL-visninger er virtuelle tabeller. Posterne i en visning er resultatet af en forespørgsel inde i den. Når basistabellerne, der bruges i visningen, bliver opdateret, opdaterer den også visningen. Du kan også INDSÆTTE, OPDATERE og SLETTE poster i en visning som en tabel i nogle tilfælde. Selvom jeg ikke selv har prøvet dette.

På samme måde som en tabel kan du OPRETTE, ÆNDRE eller SLIPPE en visning. Du kan endda oprette et indeks med nogle begrænsninger.

Bemærk, at jeg brugte SQL Server 2019 i eksempelkoderne.

1. Kend den korrekte og ukorrekte brug af SQL-visninger

Først det grundlæggende.

Hvad er SQL-visninger til?

Det er afgørende. Hvis du bruger den som en hammer til en skruetrækker, så glem alt om hurtigere SQL-visninger. Lad os først huske den korrekte brug:

  • For at fokusere, forenkle og tilpasse den opfattelse, hver bruger har af databasen.
  • For at give brugerne adgang til de eneste oplysninger, de behøver at se af sikkerhedsmæssige årsager.
  • At give bagudkompatibilitet til en gammel tabel eller et gammelt skema for ikke at bryde afhængige apps. Det er midlertidigt, indtil alle de nødvendige ændringer er gennemført.
  • For at partitionere data, der kommer fra forskellige servere. Derfor ser de ud, som om de er én tabel fra én server eller instans.

Hvordan bruger man IKKE SQL Server-visninger?

  • Genbrug visningen i en anden visning, der vil blive genbrugt i endnu en visning. Kort sagt, dybt indlejrede udsigter. Genbrug af koden har nogle få ulemper i dette tilfælde.
  • Gem ved tastetryk. Det vedrører den første, som reducerer fingertrykket og ser ud til at fremskynde kodningen.

Ukorrekt brug af visninger, hvis det er tilladt, vil sløre den egentlige årsag til, at du opretter visninger. Som du vil se senere, opvejer de reelle fordele de opfattede fordele ved ukorrekt brug.

Eksempel

Lad os inspicere et eksempel fra Microsoft. vEmployee visning fra AdventureWorks . Her er koden:

-- Medarbejdernavne og grundlæggende kontaktoplysninger OPRET VISNING [HumanResources].[vEmployee] AS SELECT e.[BusinessEntityID] ,s.[Titel] ,s.[FirstName] ,s.[MiddleName] ,s. [Efternavn] ,s.[Suffiks] ,e.[JobTitel] ,s.[PhoneNumber] ,pnt.[Navn] AS [PhoneNumberType] ,ea.[EmailAddress] ,s.[EmailPromotion] ,a.[AddressLine1] , a.[AddressLine2] ,a.[By] ,sp.[Name] AS [StateProvinceName] ,a.[PostalCode] ,cr.[Name] AS [CountryRegionName] ,s.[Yderligere kontaktoplysninger]FRA [HumanResources].[Medarbejder ] e INNER JOIN [Person].[Person] p ON p.[BusinessEntityID] =e.[BusinessEntityID] INNER JOIN [Person].[BusinessEntityAddress] bea ON bea.[BusinessEntityID] =e.[INNER JOIN] ].[Adresse] a ON a.[AddressID] =bea.[AddressID] INNER JOIN [Person].[StateProvince] sp ON sp.[StateProvinceID] =a.[StateProvinceID] INNER JOIN [Person].[CountryRegion] cr ON cr.[CountryRegionCode] =sp.[Co untryRegionCode] LEFT YDRE JOIN [Person].[PersonPhone] pp ON pp.BusinessEntityID =p.[BusinessEntityID] LEFT YDRE JOIN [Person].[PhoneNumberType] pnt ON pp.[PhoneNumberTypeID] J Person].[E-mailadresse] ea ON p.[BusinessEntityID] =ea.[BusinessEntityID];GO

Formålet med denne visning fokuserer på medarbejdernes grundlæggende information. Hvis det er nødvendigt af en personalemedarbejder, kan den vises på en webside. Blev den genbrugt i andre visninger?

Prøv dette:

  1. I SQL Server Management Studio , se efter AdventureWorks database.
  2. Udvid mappen Visninger og se efter [HumanResources].[vEmployee].
  3. Højreklik på det, og vælg Vis afhængigheder .

Hvis du ser en anden visning afhængig af denne visning, som så afhænger af en anden visning, gav Microsoft os et dårligt eksempel. Men så er der ingen andre visningsafhængigheder.

Lad os gå videre til det næste.

2. Debunk the Myth on SQL Views

Når SQL Server behandler en SELECT fra en visning , evaluerer den koden i visningen, FØR den behandler WHERE-sætningen eller en hvilken som helst join i den ydre forespørgsel. Med flere tabeller tilsluttet, vil det være langsomt sammenlignet med en SELECT fra basistabeller med samme resultater.

Det er i hvert fald, hvad jeg fik at vide, da jeg begyndte at bruge SQL. Om det er en myte eller ej, er der kun én måde at finde ud af. Lad os vende tilbage til et praktisk eksempel.

Sådan fungerer SQL-visninger

Microsoft efterlod os ikke i mørket for at debattere i det uendelige. Vi har værktøjerne til at se, hvordan forespørgsler fungerer, såsom STATISTICS IO og den faktiske udførelsesplan . Vi vil bruge disse i alle vores eksempler. Lad os få den første.

BRUG AdventureWorksGOSELECT * FRA HumanResources.vEmployee eWHERE e.BusinessEntityID =105 

For at se, hvad der foregår, når SQL Server behandler visningen, lad os inspicere Faktisk udførelsesplan i figur 1. Vi sammenligner det med CREATE VIEW-koden for vEmployee i forrige afsnit.

Som du kan se, er de første noder, der behandles af SQL Server, dem, der bruger INNER JOIN. Derefter fortsætter den med at behandle de VENstre ydre JOIN-forbindelser.

Da vi ikke kan se en filterknude nogen steder for WHERE-sætningen, skal den være i en af ​​disse noder. Hvis du inspicerer alle noders egenskaber, vil du se WHERE-sætningen behandlet i Employee-tabellen. Jeg har vedlagt det i en boks i figur 1. For at bevise, at det er der, se figur 2 for egenskaberne for den node:

Analyse

Så havde SELECT-sætningen i vEmployee visningen er blevet evalueret eller behandlet FØR WHERE-klausulen blev anvendt? Udførelsesplanen viser, at det havde den ikke. Hvis det var, skulle det vises nærmest SELECT-knuden.

Det, jeg fik at vide, var en myte. Jeg undgik noget godt på grund af en misforståelse af den korrekte brug af SQL-visninger.

Nu hvor vi ved hvordan SQL Server behandler en SELECT fra en visning , spørgsmålet er stadig:Er det langsommere end ikke at bruge en visning?

VÆLG FRA visning vs. VÆLG FRA basistabeller – hvilken vil køre hurtigere?

Først skal vi udtrække SELECT-sætningen inde i vEmployee se og producere det samme resultat, som vi havde, da vi brugte visningen. Koden nedenfor viser den samme WHERE-sætning:

BRUG AdventureWorksGO-- VÆLG FRA en visningVÆLG * FRA HumanResources.vEmployee eWHERE e.BusinessEntityID =105-- VÆLG FRA basistabellerVÆLG e.[BusinessEntityID] ,s.[Titel] ,s.[FirstName] .[Mellemnavn] ,s.[Efternavn] ,s.[Suffiks] ,e.[Jobtitel] ,s.[PhoneNumber] ,pnt.[Navn] AS [PhoneNumberType] ,ea.[EmailAddress] ,s.[EmailPromotion] ,a.[AddressLine1] ,a.[AddressLine2] ,a.[By] ,sp.[Name] AS [StateProvinceName] ,a.[PostalCode] ,cr.[Name] AS [CountryRegionName] ,s.[AdditionalContactInfo] FRA [HumanResources].[Medarbejder] e INNER JOIN [Person].[Person] p ON p.[BusinessEntityID] =e.[BusinessEntityID] INNER JOIN [Person].[BusinessEntityAddress] bea ON bea.[BusinessEntity.ID] =BusinessEntity. [BusinessEntityID] INNER JOIN [Person].[Adresse] a ON a.[AddressID] =bea.[AddressID] INNER JOIN [Person].[StateProvince] sp ON sp.[StateProvinceID] =a.[StateProvinceID] INNER JOIN [ Person].[CountryRegion] cr ON cr.[CountryRegionCode] =sp.[CountryRegionCode] LEFT YDRE JOIN [Person].[PersonPhone] pp ON pp.BusinessEntityID =s.[BusinessEntityID] LEFT YDRE JOIN [Person].[PhoneNumbertypeNumberTlf.NumberTypeN] ] =pnt.[PhoneNumberTypeID] VENSTRE YDRE JOIN [Person].[E-mailadresse] ea ON p.[BusinessEntityID] =ea.[BusinessEntityID]HVOR e.BusinessEntityID =105 

Derefter inspicerer vi STATISTICS IO og laver en Sammenlign Showplan . Hvor mange ressourcer vil en forespørgsel fra en visning have brug for i forhold til forespørgsel fra basistabeller? Se figur 3.

Her vil forespørgsler fra en visning eller basistabeller forbruge de samme logiske læsninger. Begge brugte 19 * 8KB sider. Baseret på dette er det uafgjort, hvem der er hurtigst. Med andre ord vil brug af en visning ikke skade ydeevnen. Lad os sammenligne den faktiske udførelsesplan af begge ved at bruge Sammenlign Showplan :

Kan du se den skraverede del af diagrammet? Hvad med QueryPlanHash af begge? Da begge forespørgsler har samme QueryPlanHash og de samme operationer, enten view- eller basistabeller behandles det samme af SQL Server .

De samme logiske læsninger og den samme plan for prøven fortæller os, at begge vil udføre det samme. At have høje logiske læsninger vil således få din forespørgsel til at køre langsomt, uanset om du bruger visninger eller ej. At kende dette faktum vil hjælpe dig med at løse problemet og få din udsigt til at køre hurtigere.

Desværre er der nogle dårlige nyheder.

Sammenslutning af SQL-visninger til tabeller

Det, du så tidligere, er en SELECT fra en visning uden joinforbindelser. Men hvad nu hvis du forbinder et bord med en visning?

Lad os gennemgå et andet eksempel. Denne gang bruger vi vSalesPerson se i AdventureWorks – en sælgerliste med kontaktoplysninger og salgskvote. Igen sammenligner vi sætningen med en SELECT fra basistabeller:

-- få de samlede salgsordrer for hver sælger-- ved hjælp af visningen sammenføjet med SalesOrderHeaderSELECT sp.FirstName,sp.MiddleName,sp.LastName,SUM(soh.TotalDue) AS TotalSalesOrdersFROM Sales.vSalesPerson SPINNER JOIN Sales .SalesOrderHeader soh ON sp.BusinessEntityID =soh.SalesPersonIDGROUP BY sp.LastName, sp.MiddleName, sp.FirstName-- ved hjælp af basistabellerSELECT p.FirstName,p.MiddleName,p.LastName,SUM(soh.TotalDue) AS TotalSalesOrdersFROM TotalSalesOrders. SalesPerson spinner JOIN Person.Person p ON sp.BusinessEntityID =P.BusinessEntityIDINNER JOIN Sales.SalesOrderHeader soh ON sp.BusinessEntityID =soh.SalesPersonIDGROUP BY p.LastName, p.MiddleName, p.Fir> 

Hvis du tror, ​​det også vil være det samme, så tjek STATISTICS IO:

Overrasket? Tilmelding til vSalesPerson se med SalesOrderHeader tabellen har brug for enorme ressourcer (28.240 x 8KB) sammenlignet med blot at bruge basistabellerne (774 x 8KB). Bemærk også, at det indeholdt nogle borde, vi ikke havde brug for (bordene i røde felter). Endsige højere logiske læsninger på SalesOrderHeader når du bruger visningen.

Men det slutter ikke der.

Den faktiske udførelsesplan afslører mere

Bemærk den faktiske udførelsesplan for forespørgslen til basistabeller:

Illustrationen ser ud til at vise en ret normal udførelsesplan. Men tjek den med udsigten:

Udførelsesplanen i figur 7 falder sammen med STATISTIK IO i figur 5. Vi kan se de tabeller, vi ikke har brug for, fra visningen. Der er også et nøgleopslag node med et rækkeestimat, der er mere end tusind poster væk end de faktiske rækker. Til sidst kommer der også en advarsel i SELECT-knuden. Hvad kan det være?

Hvad er det ExcessiveGrant advarsel i SELECT-knuden?

En overdreven bevilling sker, når den maksimalt brugte hukommelse er for lille sammenlignet med den bevilgede hukommelse. I dette tilfælde blev der givet 1024 KB, men kun 16 KB blev brugt.

Memory Grant er den anslåede mængde hukommelse i KB, der kræves for at køre planen.

Det kan være de forkerte estimater i Nøgleopslag node og/eller medtagelsen af ​​de tabeller, vi ikke havde brug for i planen, der forårsagede dette. Også for meget givet hukommelse kan forårsage blokering. De resterende 1008 KB kunne have været nyttige til andre operationer.

Til sidst gik noget galt, da du sluttede dig til udsigten med et bord. Vi behøver ikke at håndtere disse problemer, hvis vi spørger fra basistabellerne.

Takeaways

Det var en lang forklaring. Vi ved dog, at visninger ikke evalueres eller behandles FØR en WHERE-klausul eller joinforbindelser i den ydre forespørgsel evalueres. Vi beviste også, at begge ville præstere det samme.

På den anden side er der et tilfælde, når vi samler en udsigt til et bord. Den bruger sammenføjninger af tabeller, vi ikke har brug for fra visningen. De er usynlige for os, medmindre vi tjekker STATISTIK IO og den faktiske udførelsesplan. Det hele kan skade ydeevnen, og problemer kan komme ud af ingenting.

Derfor:

  • Vi bør vide, hvordan forespørgsler, herunder visninger, fungerer indefra.
  • STATISTIK IO og faktiske udførelsesplaner vil afsløre, hvordan forespørgsler og visninger vil fungere.
  • Vi kan ikke bare forbinde en visning til en tabel og genbruge den skødesløst. Tjek altid STATISTICS IO og faktiske udførelsesplaner! I stedet for at genbruge visninger og indlejre dem til "forbedret" kodningsproduktivitet, bruger jeg en IntelliSense og kodefuldførelsesværktøjet som SQL Complete.

Så kan vi være sikre på ikke at skrive visninger, der vil have korrekte resultater, men som kører som en snegl.

3. Prøv indekserede visninger

Indekserede visninger er, hvad navnet antyder. Det kan give et ydelsesboost til SELECT-udsagn. Men ligesom tabelindekser kan det påvirke ydeevnen, hvis basistabellerne er store og løbende opdateres.

For at se, hvordan indekserede visninger kan forbedre forespørgselsydeevnen, lad os undersøge vStateProvinceCountryRegion se i AdventureWorks . Visningen er indekseret på StateProvinceID og CountryRegionCode . Det er et klynget, unikt indeks.

Lad os sammenligne STATISTIK IO for visningen, der ikke har indekset og har et indeks. Med dette lærer vi, hvor mange 8KB sider vores SQL Server vil læse:

Figuren viser, at have et indeks i vStateProvinceCountryRegion visning reducerer logiske læsninger til det halve. Det er en forbedring på 50 % i forhold til ikke at have et indeks.

Det er godt at høre.

Stadig igen, lad være med at tilføje indekser til dine synspunkter uforsigtigt. Udover at have en lang liste af strenge regler for at have 1 unikt, klynget indeks, kan det skade ydeevnen, ligesom at tilføje indekser til tabeller. Tjek også STATISTICS IO, hvis der er et fald i logiske læsninger efter tilføjelse af indekset.

Takeaways

Som vi har set i vores eksempel, kan indekserede visninger forbedre SQL-visningernes ydeevne.

BONUS Tip

Ligesom enhver anden forespørgsel vil SQL-visninger køre hurtigt, hvis:

  • Statistikken er opdateret
  • Manglende indekser tilføjes
  • Indekser er defragmenteret
  • Indekser brugte den rigtige FILLFACTOR

Konklusion

Er SQL-visninger gode eller dårlige?

SQL-visninger er gode, hvis vi skriver dem korrekt og tjekker, hvordan de vil blive behandlet. Vi har værktøjer som STATISTICS IO og Actual Execution Plan – brug dem! Indekserede visninger kan også forbedre ydeevnen.

Kan du lide dette indlæg? Del venligst lidt kærlighed på din foretrukne sociale medieplatform.


  1. Den nemme guide til, hvordan du bruger underforespørgsler i SQL Server

  2. Returner alle mulige kombinationer af værdier på kolonner i SQL

  3. Hvad er en større version alligevel?

  4. hvordan ændres bjælkefarve i MPandroidCharts baseret på en individuel værdi gemt i sqlite?