sql >> Database >  >> RDS >> Sqlserver

Hoe rij voor rij-uitvoering te converteren naar een op SET gebaseerde benadering in SQL

Totdat de tabelstructuur en de verwachte voorbeeldgegevens voor het resultaat niet worden verstrekt, volgen hier een paar snelle dingen die volgens mij kunnen worden verbeterd (sommige zijn hierboven al door anderen genoemd):

  1. WHILE Loop is ook een cursor. Dus het veranderen in een while-lus maakt de dingen niet sneller.
  2. Gebruik de LOCAL FAST_FORWARD cursor, tenzij je een record terug moet volgen. Dit zou de uitvoering veel sneller maken.
  3. Ja, ik ben het ermee eens dat een op SET gebaseerde aanpak in de meeste gevallen het snelst zou zijn, maar als je ergens tussenliggende resultaten moet opslaan, raad ik aan om een ​​tijdelijke tabel te gebruiken in plaats van een tabelvariabele. Temp table is 'lesser evil' tussen deze 2 opties. Hier zijn een paar redenen waarom u het gebruik van een tabelvariabele zou moeten vermijden:

    • Omdat SQL Server geen eerdere statistieken over de tabelvariabele zou hebben tijdens het bouwen aan het uitvoeringsplan, wordt er altijd rekening mee gehouden dat slechts één record door de tabelvariabele wordt geretourneerd tijdens het opstellen van het uitvoeringsplan. En dienovereenkomstig zou Storage Engine slechts zoveel RAM-geheugen toewijzen voor het uitvoeren van de query. Maar in werkelijkheid kunnen er miljoenen records zijn die de tabelvariabele tijdens de uitvoering kan bevatten. Als dat gebeurt, wordt SQL Server gedwongen de gegevens tijdens de uitvoering naar de harde schijf te morsen (en u zult veel PAGEIOLATCH zien in sys.dm_os_wait_stats), waardoor de query's veel langzamer worden.
    • Een manier om van het bovenstaande probleem af te komen, is door een hint op instructieniveau OPTION (RECOMPILE) te geven aan het einde van elke query waarbij een tabelwaarde wordt gebruikt. Dit zou SQL Server dwingen om het uitvoeringsplan van die query's elke keer tijdens runtime op te stellen en het minder geheugentoewijzingsprobleem kan worden vermeden. Het nadeel hiervan is echter:SQL Server kan niet langer profiteren van een reeds in de cache opgeslagen uitvoeringsplan voor die opgeslagen procedure, en zou elke keer opnieuw moeten worden gecompileerd, wat de prestaties tot op zekere hoogte zou verslechteren. Dus tenzij u weet dat gegevens in de onderliggende tabel vaak veranderen of de opgeslagen procedure zelf niet vaak wordt uitgevoerd, wordt deze aanpak niet aanbevolen door Microsoft MVP's.


  1. SQL Server-taakactiviteit (taak is mislukt, maar geschiedenisrecords in taakactiviteit tonen nog steeds de status 'actief')

  2. Invoegen in MySQL Table PHP

  3. Kan COM-object van het type 'System.__ComObject' niet casten naar het interfacetype 'Microsoft.VisualStudio.OLE.Interop.IServiceProvider'

  4. SQL Dynamische ASC en DESC