sql >> Databasteknik >  >> RDS >> Database

De tre bästa tipsen du behöver veta för att skriva snabbare SQL-vyer

Vän eller fiende? SQL Server-vyer har varit föremål för heta debatter när jag under mitt första år använde SQL Server. De sa att det var dåligt eftersom det gick långsamt. Men hur är det idag?

Är du på samma båt som jag var för många år sedan? Följ sedan med mig på denna resa för att reda ut den verkliga affären om SQL-vyer så att du kan skriva dem så snabbt som möjligt.

SQL-vyer är virtuella tabeller. Posterna i en vy är resultatet av en fråga inuti den. När bastabellerna som används i vyn uppdateras uppdateras vyn också. Du kan också INFOGA, UPPDATERA och RADERA poster i en vy som en tabell i vissa fall. Fast jag har inte provat detta själv.

På samma sätt som för en tabell kan du SKAPA, ÄNDRA eller SLAPPA en vy. Du kan till och med skapa ett index, med vissa begränsningar.

Observera att jag använde SQL Server 2019 i exempelkoderna.

1. Känna till korrekt och felaktig användning av SQL-vyer

Först grunderna.

Vad är SQL-vyer till för?

Det är avgörande. Om du använder den som en hammare till en skruvmejsel, glöm snabbare SQL-vyer. Låt oss först komma ihåg den korrekta användningen:

  • För att fokusera, förenkla och anpassa uppfattningen varje användare har av databasen.
  • För att ge användarna tillgång till den enda information de behöver se av säkerhetsskäl.
  • För att tillhandahålla bakåtkompatibilitet till en gammal tabell eller ett gammalt schema för att inte bryta beroende appar. Det är tillfälligt tills alla nödvändiga ändringar är klara.
  • Att partitionera data som kommer från olika servrar. Därför ser de ut som om de är en tabell från en server eller instans.

Hur använder man INTE SQL Server-vyer?

  • Återanvänd vyn i en annan vy som kommer att återanvändas i ännu en vy. Kort sagt, djupt kapslade vyer. Återanvändningen av koden har några nackdelar i det här fallet.
  • Spara vid tangenttryckningar. Den hänför sig till den första, som minskar fingertrycket och verkar påskynda kodningen.

Felaktig användning av vyer, om det är tillåtet, kommer att skymma den verkliga anledningen till att du skapar vyer. Som du kommer att se senare uppväger de verkliga fördelarna de upplevda fördelarna med felaktig användning.

Exempel

Låt oss inspektera ett exempel från Microsoft. vEmployee vy från AdventureWorks . Här är koden:

-- Employee names and basic contact information
CREATE VIEW [HumanResources].[vEmployee] 
AS 
SELECT 
    e.[BusinessEntityID]
    ,p.[Title]
    ,p.[FirstName]
    ,p.[MiddleName]
    ,p.[LastName]
    ,p.[Suffix]
    ,e.[JobTitle]  
    ,pp.[PhoneNumber]
    ,pnt.[Name] AS [PhoneNumberType]
    ,ea.[EmailAddress]
    ,p.[EmailPromotion]
    ,a.[AddressLine1]
    ,a.[AddressLine2]
    ,a.[City]
    ,sp.[Name] AS [StateProvinceName] 
    ,a.[PostalCode]
    ,cr.[Name] AS [CountryRegionName] 
    ,p.[AdditionalContactInfo]
FROM [HumanResources].[Employee] e
    INNER JOIN [Person].[Person] p
 ON p.[BusinessEntityID] = e.[BusinessEntityID]
    INNER JOIN [Person].[BusinessEntityAddress] bea 
        ON bea.[BusinessEntityID] = e.[BusinessEntityID] 
    INNER JOIN [Person].[Address] 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 OUTER JOIN [Person].[PersonPhone] pp
        ON pp.BusinessEntityID = p.[BusinessEntityID]
    LEFT OUTER JOIN [Person].[PhoneNumberType] pnt
        ON pp.[PhoneNumberTypeID] = pnt.[PhoneNumberTypeID]
    LEFT OUTER JOIN [Person].[EmailAddress] ea
        ON p.[BusinessEntityID] = ea.[BusinessEntityID];
GO

Syftet med denna vy fokuserar på grundläggande information om anställda. Om det behövs av en personalpersonal kan det visas på en webbsida. Återanvändes den i andra vyer?

Prova detta:

  1. I SQL Server Management Studio , leta efter AdventureWorks databas.
  2. Utöka mappen Visningar och leta efter [HumanResources].[vEmployee].
  3. Högerklicka på den och välj Visa beroenden .

Om du ser en annan vy beroende på denna vy, som sedan beror på en annan vy, gav Microsoft oss ett dåligt exempel. Men då finns det inga andra vyberoenden.

Låt oss gå vidare till nästa.

2. Debunk the Myth on SQL Views

När SQL Server bearbetar en SELECT från en vy , utvärderar den koden i vyn INNAN den behandlar WHERE-satsen eller någon join i den yttre frågan. Med fler tabeller anslutna kommer det att gå långsamt jämfört med en SELECT från bastabeller med samma resultat.

Åtminstone var det vad jag fick höra när jag började använda SQL. Oavsett om det är en myt eller inte, det finns bara ett sätt att ta reda på det. Låt oss gå till ett praktiskt exempel.

Så fungerar SQL-vyer

Microsoft lämnade oss inte i mörkret för att diskutera oändligt. Vi har verktygen för att se hur frågor fungerar, till exempel STATISTICS IO och Faktisk utförandeplan . Vi kommer att använda dessa i alla våra exempel. Låt oss ta den första.

USE AdventureWorks
GO

SELECT * FROM HumanResources.vEmployee e
WHERE e.BusinessEntityID = 105

För att se vad som händer när SQL Server bearbetar vyn, låt oss inspektera Faktisk exekveringsplan i figur 1. Vi jämför det med CREATE VIEW-koden för vEmployee i föregående avsnitt.

Som du kan se är de första noderna som bearbetas av SQL Server de som använder INNER JOIN. Sedan fortsätter den att bearbeta LEFT OUTER JOINs.

Eftersom vi inte kan se en filternod någonstans för WHERE-satsen, måste den finnas i en av dessa noder. Om du inspekterar alla noders egenskaper kommer du att se WHERE-satsen bearbetad i Employee-tabellen. Jag har bifogat den i en ruta i figur 1. För att bevisa att den finns där, se figur 2 för egenskaperna för den noden:

Analys

Så, hade SELECT-satsen i vEmployee vyn har utvärderats eller bearbetats INNAN WHERE-klausulen tillämpades? Genomförandeplanen visar att den inte hade gjort det. Om det var det, bör det visas närmast SELECT-noden.

Det jag fick höra var en myt. Jag undvek något bra på grund av ett missförstånd av korrekt användning av SQL-vyer.

Nu när vi vet hur SQL Server bearbetar en SELECT från en vy , frågan kvarstår:Är det långsammare än att inte använda en vy?

VÄLJ FRÅN vy kontra VÄLJ FRÅN bastabeller – vilken kommer att gå snabbare?

Först måste vi extrahera SELECT-satsen inuti vEmployee visa och producera samma resultat som vi hade när vi använde vyn. Koden nedan visar samma WHERE-sats:

USE AdventureWorks
GO

-- SELECT FROM a view
SELECT * FROM HumanResources.vEmployee e
WHERE e.BusinessEntityID = 105

-- SELECT FROM Base Tables
SELECT 
    e.[BusinessEntityID]
    ,p.[Title]
    ,p.[FirstName]
    ,p.[MiddleName]
    ,p.[LastName]
    ,p.[Suffix]
    ,e.[JobTitle]  
    ,pp.[PhoneNumber]
    ,pnt.[Name] AS [PhoneNumberType]
    ,ea.[EmailAddress]
    ,p.[EmailPromotion]
    ,a.[AddressLine1]
    ,a.[AddressLine2]
    ,a.[City]
    ,sp.[Name] AS [StateProvinceName] 
    ,a.[PostalCode]
    ,cr.[Name] AS [CountryRegionName] 
    ,p.[AdditionalContactInfo]
FROM [HumanResources].[Employee] e
    INNER JOIN [Person].[Person] p
	ON p.[BusinessEntityID] = e.[BusinessEntityID]
    INNER JOIN [Person].[BusinessEntityAddress] bea 
        ON bea.[BusinessEntityID] = e.[BusinessEntityID] 
    INNER JOIN [Person].[Address] 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 OUTER JOIN [Person].[PersonPhone] pp
        ON pp.BusinessEntityID = p.[BusinessEntityID]
    LEFT OUTER JOIN [Person].[PhoneNumberType] pnt
        ON pp.[PhoneNumberTypeID] = pnt.[PhoneNumberTypeID]
    LEFT OUTER JOIN [Person].[EmailAddress] ea
        ON p.[BusinessEntityID] = ea.[BusinessEntityID]
WHERE e.BusinessEntityID = 105

Sedan inspekterar vi STATISTICS IO och gör en jämför showplan . Hur många resurser kommer en fråga från en vy att behöva i jämförelse med fråga från bastabeller? Se figur 3.

Här kommer fråga från en vy eller bastabeller att förbruka samma logiska läsningar. Båda använde 19 * 8KB sidor. Baserat på detta är det oavgjort vem som är snabbast. Med andra ord, att använda en vy kommer inte att skada prestandan. Låt oss jämföra Faktisk utförandeplan av båda med hjälp av Jämför Showplan :

Ser du den skuggade delen av diagrammet? Vad sägs om QueryPlanHash av båda? Eftersom båda frågorna har lika QueryPlanHash och samma operationer, antingen vy- eller bastabeller bearbetas på samma sätt av SQL Server .

Samma logiska läsningar och samma plan för provet säger oss att båda kommer att utföra samma sak. Med höga logiska läsningar kommer alltså din fråga att gå långsamt oavsett om du använder vyer eller inte. Att känna till detta kommer att hjälpa dig att åtgärda problemet och göra din vy snabbare.

Tyvärr finns det dåliga nyheter.

Sammanfogar SQL-vyer till tabeller

Det du såg tidigare är en SELECT från en vy utan kopplingar i den. Men vad händer om du ansluter ett bord till en vy?

Låt oss granska ett annat exempel. Den här gången använder vi vSalesPerson visa i AdventureWorks – en säljarlista med kontaktuppgifter och försäljningskvot. Återigen jämför vi uttalandet med en SELECT från bastabeller:

-- get the total sales orders for each salesperson
-- using the view joined with SalesOrderHeader
SELECT 
 sp.FirstName
,sp.MiddleName
,sp.LastName
,SUM(soh.TotalDue) AS TotalSalesOrders
FROM Sales.vSalesPerson sp
INNER JOIN Sales.SalesOrderHeader soh ON sp.BusinessEntityID = soh.SalesPersonID
GROUP BY sp.LastName, sp.MiddleName, sp.FirstName

-- using base tables
SELECT
 p.FirstName
,p.MiddleName
,p.LastName
,SUM(soh.TotalDue) AS TotalSalesOrders
FROM sales.SalesPerson sp
INNER JOIN Person.Person p ON sp.BusinessEntityID = P.BusinessEntityID
INNER JOIN Sales.SalesOrderHeader soh ON sp.BusinessEntityID = soh.SalesPersonID
GROUP BY p.LastName, p.MiddleName, p.FirstName 

Om du tror att det också kommer att vara samma, kontrollera STATISTICS IO:

Överraskad? Gå med i vSalesPerson visa med SalesOrderHeader Tabellen behöver enorma resurser (28 240 x 8KB) jämfört med att bara använda bastabellerna (774 x 8KB). Observera också att det inkluderade några bord som vi inte behövde (borden i röda rutor). Låt vara högre logiska läsningar på SalesOrderHeader när du använder vyn.

Men det slutar inte där.

Den faktiska genomförandeplanen avslöjar mer

Lägg märke till den faktiska exekveringsplanen för frågan till bastabeller:

Illustrationen verkar visa en ganska normal utförandeplan. Men kolla in den med utsikten:

Utförandeplanen i figur 7 sammanfaller med STATISTICS IO i figur 5. Vi kan se tabellerna vi inte behöver från vyn. Det finns också en nyckelsökning nod med en raduppskattning som är mer än tusen poster borta än de faktiska raderna. Slutligen visas också en varning i SELECT-noden. Vad kan det vara?

Vad är det där Excessive Grant varning i SELECT-noden?

Ett överdrivet anslag inträffar när det maximalt använda minnet är för litet jämfört med det beviljade minnet. I det här fallet beviljades 1024 kB, men endast 16 kB användes.

Memory Grant är den uppskattade mängden minne i KB som krävs för att köra planen.

Det kan vara fel uppskattningar i Nyckelsökning nod och/eller inkluderingen av tabellerna som vi inte behövde i planen som orsakade detta. Dessutom kan för mycket beviljat minne orsaka blockering. De återstående 1008 KB kunde ha varit användbara för andra operationer.

Så småningom gick något fel när du gick med i utsikten med ett bord. Vi behöver inte ta itu med dessa problem om vi frågar från bastabellerna.

Hämtmat

Det var en lång förklaring. Vi vet dock att vyer inte utvärderas eller bearbetas INNAN en WHERE-sats eller kopplingar i den yttre frågan utvärderas. Vi bevisade också att båda skulle prestera likadant.

Å andra sidan finns det ett fall när vi slår samman en vy till ett bord. Den använder sammanfogningar av tabeller som vi inte behöver från vyn. De är osynliga för oss om vi inte kontrollerar STATISTIK IO och den faktiska genomförandeplanen. Allt kan skada prestandan och problem kan komma från ingenstans.

Därför:

  • Vi bör veta hur frågor, inklusive vyer, fungerar inifrån.
  • STATISTIK IO och faktiska utförandeplaner kommer att avslöja hur frågor och vyer kommer att fungera.
  • Vi kan inte bara sammanfoga en vy till en tabell och återanvända den slarvigt. Kontrollera alltid STATISTICS IO och faktiska utförandeplaner! Istället för att återanvända vyer och kapsla in dem för "förbättrad" kodningsproduktivitet, använder jag en IntelliSense och kodkompletteringsverktyget som SQL Complete.

Vi kan då vara säkra på att inte skriva vyer som kommer att få korrekta resultat utan som går som en snigel.

3. Testa indexerade vyer

Indexerade vyer är vad namnet antyder. Det kan ge en prestandahöjning till SELECT-satser. Men precis som tabellindex kan det påverka prestandan om bastabellerna är stora och kontinuerligt uppdateras.

För att se hur indexerade vyer kan förbättra frågeprestanda, låt oss undersöka vStateProvinceCountryRegion visa i AdventureWorks . Vyn är indexerad på StateProvinceID och CountryRegionCode . Det är ett klustrat, unikt index.

Låt oss jämföra STATISTICS IO för vyn som inte har indexet och har ett index. Med detta lär vi oss hur många 8KB sidor vår SQL Server kommer att läsa:

Bilden visar att ha ett index i vStateProvinceCountryRegion view reducerar logiska läsningar med hälften. Det är en förbättring på 50 % jämfört med att inte ha något index.

Det är bra att höra.

Ändå, återigen, lägg inte till index till dina åsikter slarvigt. Förutom att ha en lång lista med strikta regler för att ha ett unikt, klustrat index, kan det skada prestandan, ungefär som att lägga till index i tabeller överflödigt. Kontrollera också STATISTICS IO om det finns en minskning av logiska läsningar efter att indexet lagts till.

Hämtmat

Som vi har sett i vårt exempel kan indexerade vyer förbättra SQL-vyernas prestanda.

BONUStips

Precis som alla andra frågor kommer SQL-vyer att köras snabbt om:

  • Statistiken uppdateras
  • Saknade index läggs till
  • Index är defragmenterade
  • Index använde rätt FILLFACTOR

Slutsats

Är SQL-vyer bra eller dåliga?

SQL-vyer är bra om vi skriver dem korrekt och kontrollerar hur de kommer att behandlas. Vi har verktyg som STATISTICS IO och Faktisk Execution Plan – använd dem! Indexerade vyer kan också förbättra prestandan.

Gillar du det här inlägget? Dela gärna lite kärlek på din favoritplattform för sociala medier.


  1. Skicka och returnera anpassade arrayobjekt i ibatis och oracle i java

  2. brew installera mysql på macOS

  3. PDO:MySQL-servern har försvunnit

  4. Hur man lägger till tid till ett Datetime-värde i MySQL