Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come convertire l'esecuzione riga per riga in un approccio basato su SET in SQL

Fino a quando non vengono forniti la struttura della tabella e i dati di esempio dei risultati attesi, ecco alcune cose rapide che possono essere migliorate (alcune di queste sono già menzionate da altri sopra):

  1. WHILE Loop è anche un cursore. Quindi, passare al ciclo while non renderà le cose più veloci.
  2. Utilizzare il cursore LOCAL FAST_FORWARD a meno che non sia necessario eseguire il backtrack di un record. Ciò renderebbe l'esecuzione molto più veloce.
  3. Sì, sono d'accordo sul fatto che avere un approccio basato su SET sarebbe il più veloce nella maggior parte dei casi, tuttavia se è necessario archiviare un set di risultati intermedio da qualche parte, suggerirei di utilizzare una tabella temporanea anziché una variabile di tabella. La tabella temporanea è "male minore" tra queste 2 opzioni. Ecco alcuni motivi per cui dovresti evitare di utilizzare una variabile di tabella:

    • Poiché SQL Server non avrebbe alcuna statistica precedente sulla variabile di tabella durante la creazione del piano di esecuzione, considererà sempre che un solo record verrebbe restituito dalla variabile di tabella durante la creazione del piano di esecuzione. E di conseguenza Storage Engine assegnerebbe solo la stessa quantità di memoria RAM per l'esecuzione della query. Ma in realtà, potrebbero esserci milioni di record che la variabile di tabella potrebbe contenere durante l'esecuzione. Se ciò accade, SQL Server verrebbe forzato a trasferire i dati sul disco rigido durante l'esecuzione (e vedrai molti PAGEIOLATCH in sys.dm_os_wait_stats) rendendo le query molto più lente.
    • Un modo per sbarazzarsi del problema di cui sopra sarebbe fornire un suggerimento a livello di istruzione OPTION (RICIMPILA) alla fine di ogni query in cui viene utilizzato un valore di tabella. Ciò costringerebbe SQL Server a creare il piano di esecuzione di tali query ogni volta durante il runtime e si possono evitare problemi di allocazione di memoria inferiori. Tuttavia, lo svantaggio di questo è:SQL Server non sarà più in grado di sfruttare un piano di esecuzione già memorizzato nella cache per quella stored procedure e richiederebbe la ricompilazione ogni volta, il che deteriorerebbe le prestazioni in una certa misura. Pertanto, a meno che tu non sappia che i dati nella tabella sottostante cambiano frequentemente o che la procedura memorizzata stessa non viene eseguita frequentemente, questo approccio non è consigliato dagli MVP di Microsoft.