2010-01-26 13 views
16

Ho usato le procedure di memorizzazione CLR in SQL server per un po 'di tempo, ma mi chiedo ancora quali siano le migliori situazioni per usarle.Quali sono i buoni problemi da risolvere utilizzando i proc memorizzati con CLR?

MSDN fornisce alcune linee guida per l'uso come la manipolazione di stringhe pesanti (regex) o la sostituzione di T-SQL che dichiara molte variabili di tabella e cursori. Sono curioso di sapere quali sono i problemi che gli utenti SO stanno risolvendo con i proc di memorizzazione CLR e gli esempi/benchmark.

Ad esempio, ho trovato che i processi di memorizzazione CLR memorizzati + SSRS sono un ottimo modo per ottenere la logica di manipolazione dei dati da SSRS e da T-SQL e in codice gestito che è più facile da leggere e manipolare.

risposta

23

Molti problemi che richiedono denormalizzazione e/o operazioni sequenziali possono essere gestite eccezionalmente bene dal CLR e possono essere utilizzati per migliorare notevolmente le prestazioni senza sacrificare l'usabilità sull'estremità SQL (tanto). Invece di affidarsi interamente a operazioni basate su set o iterative, puoi adottare un approccio ibrido, utilizzare una soluzione basata su set per le grandi tratte e passare a un modello iterativo per i loop stretti.

I tipi integrati hierarchyid e geospaziali (ovvero geography) in SQL Server 2008 sono buoni esempi del problema denormalizzazione. Entrambi contengono una quantità di dati (quasi) arbitrariamente difficili da normalizzare senza compromettere le prestazioni: è necessario ricorrere a ricorsioni o cursori per eseguire altrimenti un lavoro significativo con loro, oppure utilizzare un numero di trigger e/o attività pianificate per ratto mantenere una tabella denormalizzazione.

Un altro problema che ho risolto con i tipi CLR è la compressione in linea. Questo potrebbe sembrare un esercizio inutile o accademico, ma quando i dati completamente normalizzati stanno spingendo nel terabyte, una riduzione dell'80-90% delle dimensioni significa molto. Ora SQL ha la sua compressione incorporata e SQL 2005 ha il vardecimal, e anche quelli sono buoni strumenti, ma un algoritmo di "minimizzazione" consapevole del dominio può essere più volte più efficiente in termini di carico della CPU e di compressione. Ovviamente questo non si applica ad ogni problema, ma si applica ad alcuni.

Ancora un altro problema molto frequente trovato in questo sito è generare una sequenza al volo - ad esempio una sequenza di date consecutive.Le soluzioni comuni sono CTE ricorsive, tabelle di sequenze statiche e le note tabelle spt_values poco note, ma una semplice UDF CLR offre prestazioni migliori di tutte e offre una maggiore flessibilità.

Ultimo nella mia lista: Gli aggregati di streaming definiti dall'utente sono anche molto utili, specialmente per qualsiasi argomento relativo alle statistiche. Ci sono alcune cose che non puoi semplicemente comporre dagli aggregati SQL incorporati, come mediane, medie mobili ponderate, ecc. Gli UDA possono anche prendere più argomenti in modo da poterli parametrizzare; tecnicamente non è garantito che un aggregato riceva dati in un ordine particolare nella versione corrente di SQL Server, ma è possibile aggirare tale limite alimentandolo a ROW_NUMBER come argomento aggiuntivo e utilizzarlo per implementare praticamente qualsiasi funzione di windowing (avere l'aggregato sputa un UDT che può quindi essere trasformato in una tabella).

In realtà è davvero frustrante il numero limitato di esempi di applicazioni SQL-CLR veramente utili; cerca su Google e otterrai 10 milioni di risultati, ognuno dei quali per una sciocca concatenazione di stringhe o regex. Questi sono utili, ma prendi qualche minuto per conoscere gli UDT e gli UDA di SQL in particolare e inizierai a vedere molti usi per loro nelle tue applicazioni. Non impazzire, ovviamente - pensa attentamente se esiste o meno una soluzione migliore in puro SQL - ma non sottovalutali neanche.

+2

Questo è uno dei post più istruttivi che abbia mai letto. Grazie. –

+0

+1 mette molto bene –

5

Manipolazione stringa: la ricerca di espressioni regolari è un classico. Molto facile da esporre in CLR, molto difficile da fare in T-SQL dritto.

Vedere this link per i dettagli di implementazione e un micro-benchmark (SQLCLR is only 47 milliseconds compared to 6.187 seconds for the T-SQL UDF).

5

La manipolazione delle stringhe (regex) è già stata menzionata, ma anche l'aritmetica DateTime e, naturalmente, un altro biggy, che chiama servizi Web esterni.

+0

Hey Marc, puoi dare un esempio di un problema che potresti risolvere accedendo a servizi web esterni in un proc di CLR? +1 per l'utilità di sicuro. –

+0

Un sacco di cose - ad es. ottenere i tassi di cambio valuta aggiornati, ottenere informazioni aggiornate sulle scorte e molto altro ancora –

2
  • personalizzato aggrega
  • manipolazione di stringhe
  • tipi di dati personalizzati

Per essere onesti, io vedo solo la gestione delle stringhe che include CSV suddivisione in righe.

Considererei tutto ciò che ha bisogno di più del livello di attendibilità predefinito per essere fuori dai limiti, a meno che non fossi un DBA che fa cose tipo DBA.

da MSDN con RegEx e feed RSS esempi: Using CLR Integration in SQL Server 2005

3

Ecco un esempio di qualcosa che ho usato procs CLR per questo ho pensato è stata ordinata:

aggiornamenti dei dati Timed da webservices esterni che utilizzano CLR memorizzato procs e posti di lavoro SQL.

Abbiamo un'applicazione che sincronizza alcuni dei dati tracciati con feed di dati di settore esterni. La sincronizzazione viene eseguita settimanalmente per tutto e su richiesta anche per gli aggiornamenti singoli, quindi ho avuto un'API webservice esistente per accedervi. Le cose sono già programmate da un servizio di Windows, ma ho pensato perché non essere in grado di programmarli come i nostri altri lavori SQL ??

Ho creato una procedura memorizzata CLR che si rifà all'API webservice dell'applicazione. Quindi ho aggiunto alcuni parms per @RecordID per supportare la sincronizzazione singola e pianificato in processi SQL di Enterprise manager.

Ora posso utilizzare il processo per eseguire le sincronizzazioni dB o utilizzare il proc all'interno di altri proc SQL o Trigger per aggiornare i dati dal feed esterno.

Potrebbe essere più pulito prendere l'API del servizio Web dell'applicazione in futuro e utilizzare direttamente il servizio web esterno. Per ora però, questo è stato molto veloce da implementare e un modo interessante per estendere le funzionalità al gruppo SQL.

1

È molto utile per estrarre i dati da un sistema che non fornisce un'interfaccia SQL tradizionale o l'implementazione del fornitore di tale interfaccia è sub-par.

Abbiamo un'applicazione di base costruita sulla vecchia piattaforma MUMPS, in esecuzione sul database di Intersystems Cache. I dati sono gerarchici, non di natura relazionale. L'array globale principale (tabella i.e.) ha più livelli di dati ed elementi tutti raggruppati per numero di conto. La scansione di una sola colonna richiede il caricamento dell'intero globale dal disco e richiede più di 8 ore. Il fornitore fornisce un driver ODBC e mappature ai globali, ma spesso si traduce in scansione e query estremamente lente.

Ho creato una funzione con valori di tabella che accetta un programma ObjectScript (dialetto di Intersystem di MUMPS), lo esegue sul server Cache e restituisce le righe di output come righe di dati. Posso eseguire il microgestione del percorso di accesso ai dati sul lato MUMPS (è davvero quello che serve per ottenere un accesso efficiente ai dati) fornendo un programma specifico da eseguire su quel lato e quindi importare facilmente i dati in MSSQL come origine dati in-line ad hoc.

Posso usare il TVF per guidare la selezione dei dati o usare CROSS APPLY per effettuare ricerche sull'altro capo ed è ragionevolmente efficiente. Posso anche eseguire più query sul lato remoto in parallelo se costringo MSSQL a utilizzare un piano di esecuzione parallelo.

+0

> "e restituisce le righe di output come righe di dati." Hai messo i dati in un System.Data.DataTable prima? Ho alcune funzioni di supporto per scrivere tabelle di dati, ma mi chiedo come possa essere fatto con un IEnumerable, ad esempio. – tbone

+0

Esiste un metodo FillRow con la funzione di valori di tabella di streaming, che ha una proiezione fissa di righe. Nella versione originale, ho restituito fino a 8 campi carattere dalla query come F1, F2, F3 ... –

+0

Grazie - esempio pertinente Penso: http://stackoverflow.com/questions/6901811/sql-clr-streaming- risultati a valore di tabella – tbone

Problemi correlati