MS SQL Server – Quando è un CURSORE bene?

Molte volte, quando ho scritto stored procedure, etc. Io uso un CURSORE in corrispondenza del primo e, in seguito, qualche problema di prestazioni con la mia procedura.

Ogni cosa che ho letto dice che i CURSORI sono terribili, causa di inutili di chiusura, etc. test delle prestazioni e dimostra la stessa.

La mia domanda è: quando si utilizza un CURSORE e in quali situazioni è utile o buono?

Se non c’è l’uso, perché dovrei fare una brutta struttura di controllo/tipo di SQL?

  • Chi segnato questa domanda come “Duplicato”, vorresti postare il link alla domanda originale? Quindi io voto per chiudere per “Duplicato”. Ma fino ad allora, trovo questa domanda per essere informativo.

 

9 Replies
  1. 36

    Normalmente sono da evitare, ma la funzione è lì per un motivo e ci sono i tempi per il loro utilizzo. Direi che il 90+% dei cursori ho visto che non sono necessari. Se si utilizza per le operazioni CRUD, che può quasi sempre essere rifatto in un set di moda. Ho visto spesso la gente usa i cursori per questo, perché non sanno come utilizzare unisce in un update o delete o che possono utilizzare un’istruzione select, invece di una clausola values in un inserto. Un altro uso inutile quando le persone pensano di aver bisogno di loro per un po ‘ più complessa elaborazione che in realtà potrebbe essere facilmente gestito con un’istruzione case.

    I cursori sono a volte più veloce per il calcolo di qualcosa di simile a un totale di esecuzione.

    I cursori sono anche a portata di mano per più esecuzioni di una stored proc che è impostato per gestire un solo valore di input alla volta. Io non uso questa funzione per l’esecuzione di utente stored procedure (a meno che non penso di essere di colpire un piccolo insieme di dati), ma è molto utile per gli amministratori di database quando ha bisogno di eseguire il sistema si attiva contro più tabelle.

    Se la creazione di messaggi di posta elettronica in SQl (non è il posto migliore per farlo, ma in alcuni sistemi è lì che si fa) e non si desidera che l’intera platea di email di vedere le altre persone in lista o che si desidera personalizzare ogni e-mail con le informazioni sul destinatario, i cursori sono la strada da percorrere.

    Cursori o loop può essere utilizzato anche per il processo di lotti di record se l’intero set a base di insert/update/delete troppo lungo e bloccare le tabelle. Questo è una sorta di ibrido tra i cursori e il set a base di soluzione, ed è spesso il migliore per i grandi cambiamenti nei sistemi di produzione.

    • +1 per dare solide ragioni per cui i Cursori esiste. Troppe persone pensano set di base di logica in qualche modo (a) copre tutti i possibili scenari (b) è sempre più performante di un cursore a base di soluzione, e (c) è sempre più mantenibili/leggibile. Mentre penso che la maggior parte del lavoro è fatto da set a base di approcci, nulla è mai del 100%.
    • FWIW, penso che probabilmente si potrebbe implementare un totale di esecuzione utilizzando un’Espressione di Tabella Comune, se si utilizza SQL Server 2005/2008.
    • SQL Server hanno cursore implicito sintassi? Esplicita è la solita dichiarazione con OPEN, FETCH, approccio…
    • Io sono l’unico ragazzo che ha grande familiarità con join, ma non ha idea di come usare un cursore?
    • Dopo aver evitato di cursori da ottenere andare, io sono nella stessa barca. Ora che so come usarli, mi chiedevo a cosa servono.
    • Io non capisco perché i cursori sono migliori per l’email scenario. Io sono re-introduzione di cursori dopo un lungo periodo di tempo, quindi mi piacerebbe davvero apprezzare una semplice spiegazione.
    • supponiamo che ho voluto inviare un gruppo di rappresentanti di vendita, una e-mail con i compiti a cui sono individualmente respobsible per fare prima alcune dealine come la fine di teh trimestre. Ogni e-mail saranno sostanzialmente teh stesso, ma alcuni dettagli saranno diverse. Non volete Giovanni per vedere quello che Maria ha ricevuto il compito di fare. Così si utilizza un cursore per creta singoli messaggi di posta elettronica che solo il destinatario e avere dettagli che si differenziano sulla sezione che elenca le attività.

  2. 8

    Ho chiesto a un ragazzo del team di SQL Server una sola volta, se si potesse aggiungere una caratteristica che rende il prodotto migliore per tutti che cosa sarebbe?

    La sua risposta è stata ‘Aggiungere? Eh, vorrei prendere una distanza. Se si sbarazzarsi di cursori forza di programmatori in tutto il mondo per iniziare a pensare le cose in un SET base e che sarà il più grande crescita a livello mondiale nel DB di rendimento che si potrà mai vedere.’

    Per parte mia, però io tendo a vedere un modello, sembra che ci sia un sacco di procedurali programmatori che utilizzano i cursori perché hanno bisogno di essere in grado di fare un’operazione, un elemento alla volta e perdere la vecchia moda DURANTE il ciclo concetto. Stessa idea di base, senza il cursore sopra la testa. Ancora vicino come veloce/efficace come qualcosa di base, ma il 90% delle volte quando qualcuno dice ‘non posso fare questo set base, devo usare i cursori’ posso arrivare a fare con un ciclo while.

    • Sono molto abusato, che è ciò che il ragazzo probabilmente si riferisce a, ma la domanda era per utilizzarle. Hanno un luogo in determinati casi.
    • Da “la stessa idea di base, senza il sovraccarico di cursore” stai suggerendo mentre i passanti non hanno le stesse spese generali come i cursori?
    • Utilizzando un ciclo WHILE per fare un’operazione, un elemento alla volta, invece di utilizzare un cursore per fare un’operazione, un elemento alla volta, e non modifica il funzionamento in un set a base di operazione.
    • Vorrei avere una parola con quel ragazzo troppo. Credo che sulla base di aproaches; trascorso ore e ore a cercare di scrivere di loro; cercare la rete che mi dice: “no set base, utilizzare un cursore”; poi di visitare siti come questo per imparare a utilizzare i Cursori e solo leggere cose come: “l’uso del Set di base a meno che non si può”. Così forse si dovrebbe iniziare a progettare un linguaggio che è più di lettura/scrittura SENZA(100%) la necessità di cicli invece di incolpare procedurali programmatori per l’uso di funzioni che sono stati implementati per risolvere il 10%, anche non basati su un insieme. L’attuazione di un più veloce interpretato ciclo potrebbe anche fare il trucco. 🙁
  3. 1

    Il MCTS prep manuale per SQL Server 2008 che sto studiando consiglia di utilizzare esterni codice CLR da nessuna parte che un CURSORE in T-SQL, soprattutto ora che SQL Server 2008 supporta le funzioni di aggregazione.

    5 anni fa, ho lavorato con loro per esteso le funzionalità di reporting, ma non penso che potrei venire con un buon caso di utilizzo per loro ora. CLR aggregati e funzioni di eseguire in modo analogo a built-in funzioni di aggregazione.

    • Che non è stata la mia esperienza a tutti. Invocando CLR metodi sembra proprio sopra la testa, e che si sta chiamando tale metodo in un ciclo che viene eseguito con un significativo volume abbastanza alto, le cose tendono a rallentare a una ricerca per indicizzazione. Come le cose sono state da parte tua?
    • Abbastanza bene finora, anche se, certamente, sto usando semplici funzioni. Stai parlando aggregati in particolare?
    • CLR aggregati sarebbe più utile se IsInvariantToOrder è stato implementato piuttosto riservato per uso futuro. Alcune cifre prestazioni backup CLR vs Cursori qui
  4. 1

    Unica volta che io li uso quando ciò che è stato fatto all’interno del cursore assolutamente deve essere fatto un elemento alla volta e dove tutto ciò che è stato fatto all’interno il cursore prende così a lungo che il sovraccarico del cursore scompare nell’insignificanza.

    Ad esempio i backup del database, i controlli di integrità, ricrea l’indice. In breve, l’attività di amministrazione.

  5. 1

    OMG, come ho fatto a dimenticare di Gruppo? Ho preso il cursore la ricerca che vedi qui sotto e lo ha sostituito con quello dopo di esso. Ora ho un unico set di risultati quindi non ci sono problemi con l’utilizzo di sqlsrv_next_result() in php.

    DECLARE @thisday datetime;
    
    DECLARE daycursor CURSOR FOR
    SELECT DISTINCT DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) as thisday
    FROM computerusedata
    
    OPEN daycursor;
    FETCH NEXT FROM daycursor
    INTO @thisday;
    WHILE @@FETCH_STATUS = 0
        BEGIN
        select distinct left(ComputerName,5) as CompGroup,DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) as day
        FROM computerusedata
        where DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) = @thisday
        order by CompGroup;
        FETCH NEXT FROM daycursor;
        END;
    CLOSE daycursor;
    DEALLOCATE daycursor;";
    
    
    select DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) as day,left(ComputerName,5) as CompGroup
    from ComputerUseData
    group by DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)),left(ComputerName,5)
    order by day,CompGroup
  6. 0

    Io in genere non utilizzare i cursori, ma quando ho bisogno, deve essere un “one-off” query che sono in esecuzione in locale o un lavoro quotidiano. Si vuole astenersi dall’avere il codice di produzione chiamata di un cursore che potrebbe essere richiamate spesso, come in risposta a una richiesta web.

  7. 0

    I cursori sono utili quando 1) hai bisogno di fare qualcosa che non si può fare con un’operazione impostata, o 2) non ha senso fare lo stesso lavoro da iterative chiamate dal livello di applicazione. O, a volte, si dispone di una procedura che deve rimanere sul livello del database, e semplicemente non può rompere di nuovo fuori per l’applicazione di strato midstream per iterare su alcuni set di risultati.

    Una raccomandazione che vorrei fare, però, è che le persone che utilizzano variabili di cursore piuttosto che il normale cursori, perché si evita il cursore di allocazione/deallocazione di problemi che circondano normale cursori. Con un cursore normale, se non deallocare la loro persistono, che può essere una fonte di perdite di memoria. Non è così variabile in base cursori (cioè DECLARE @cursore).

    La linea di fondo è, evitare se possibile, e se non è possibile, utilizzarli in minima parte e con saggezza.

    • Si sta dicendo (nr1): Tenta di raggiungere la vostra destinazione più veloce di un aereo, se non prendi un aereo. Questo potrebbe prendere tutta la mia vita…
    • Che non è nemmeno vicino a quello che stavo dicendo (9 anni fa). Infatti, non so nemmeno a cosa ti riferisci. Leggi tutto di nuovo, per favore.
    • Quindi, come si può sapere che non è nemmeno vicino a quello che stavi dicendo, se non avete capito cosa volevo dire? Mi dispiace per il coment a tutti, io sono pazzo di SQL e di continuare la lettura: “l’uso di un set di base di accesso a meno che non si può”. Thats una sorta di acronimo ricorsivo come GNU. Avrei bisogno di testare tutta la mia vita per farlo in base, poi, quando mi è morto il suo sicuro di dire “Per ME non era possibile, avrei potuto usare un cursore qui”.
    • scusa per non tornare a questo commento dopo aver inviato per chiarire. La tua domanda iniziale è molto bella, e il mio commento è stato pubblicato in fretta. Comunque. (1) Alcune operazioni in SQL semplicemente non può essere fatto in un’operazione impostata. (2) Alcuni potrebbe essere fatto come una operazione di impostazione, ma a causa delle dimensioni del set di dati, non dovrebbe essere fatto in quel modo, ma piuttosto in un chunked operazione. (3) Alcune operazioni non possono essere effettuate in un set approccio non importa cosa, e anche per chi, solo alcune condizioni chiamare per un cursore, se non si vuole coinvolgere il livello di applicazione. Il nostro lavoro è quello di conoscere la differenza in fretta.

Lascia un commento