2009-03-11 9 views
6

Voglio memoizzare i risultati delle funzioni per le prestazioni, ad esempio compilare pigramente una cache indicizzata sugli argomenti della funzione. La prima volta che chiamo una funzione, la cache non avrà nulla per gli argomenti di input, quindi la calcolerà e la memorizzerà prima di restituirla. Le chiamate successive usano solo la cache.Risultati della funzione di memorizzazione nella cache in SQL Server 2000

Tuttavia, sembra che SQL Server 2000 abbia una regola arbitraria stupida sulle funzioni "deterministiche". INSERT, AGGIORNAMENTI e chiamate di stored procedure regolari sono vietati. Tuttavia, sono consentite procedure archiviate estese. Come è questo deterministico? Se un'altra sessione modifica lo stato del database, l'output della funzione cambierà comunque.

Sto fumando pazzo. Avevo pensato di rendere la cache trasparente per l'utente. È possibile? Non dispongo delle autorizzazioni per l'implementazione di stored procedure estese.

EDIT:

Questa limitazione è ancora nel 2008. Non è possibile chiamare RAND, per l'amor di Dio!

La cache verrà implementata da me nel DB. La cache è qualsiasi archivio dati usata per la cache ...

EDIT:

ci sono casi in cui gli stessi argomenti a una funzione produrrà risultati diversi, al di fuori delle modifiche ai dati sottostanti. Questa è una piattaforma BI e le uniche modifiche provengono dall'ETL programmato, durante il quale avrei TRONCATO la tabella della cache.

Questi sono calcoli di serie temporali di I/O intensivo, dell'ordine di O (n^4). Non ho il mandato per modificare la tabella o gli indici sottostanti. Inoltre, molte di queste funzioni utilizzano le stesse funzioni intermedie e il caching consente di utilizzarle.

Le UDF non sono realmente deterministiche, a meno che non tengano conto dei cambiamenti nello stato del database. Qual e il punto? La memorizzazione nella cache di SQL Server è? (Ironico.) Se SQL Server è la memorizzazione nella cache, quindi deve essere in scadenza su modifiche alle tabelle che sono legati allo schema. Se sono legati allo schema, allora perché non legare le tabelle modificate dalla funzione? Posso capire perché i proc non sono permessi, anche se questo è solo sciatto; solo schema bind procs. E, BTW, perché consentire processi estesi memorizzati? Non è possibile tenere traccia di ciò che fanno questi per garantire il determinismo !!! Argh !!!

EDIT:

La mia domanda è: C'è un modo per pigramente risultati funzione di cache in un modo che può essere utilizzato in una vista?

+0

Mi dispiace, non mi era chiaro dal tuo post originale che stavi creando la cache "da zero". Come intendevi trattare casi in cui la stessa funzione, con gli stessi argomenti, dovrebbe restituire risultati diversi? –

+0

qual è la tua domanda? –

risposta

2

Deterministico significa che gli stessi ingressi restituiscono la stessa uscita indipendente dal tempo e dal database.

SQL Server (qualsiasi versione) non esegue il caching delle UDF - Credo che eviterà di chiamare l'UDF due volte su una singola riga, ma il gioco è fatto.

Un trucco che ho usato è quello di (credo che ho postato qui su SO):

Refactor l'UDF, se possibile in modo che ci sono effettivamente un sottoinsieme discreto utile di valori restituiti per un dato insieme di ingressi. Per i calcoli numerici, a volte è possibile rifattorizzare la logica per restituire un fattore o un tasso che viene moltiplicato al di fuori dell'UDF anziché moltiplicato all'interno dell'UDF da un valore passato.

Chiamare l'UDF sul set di righe DISTINCT e memorizzare i risultati in una tabella temporanea.Se si chiama solo l'UDF con 100.000 tuple di parametri su un set di 17.000.000 di righe, questo è molto molto più efficiente.

JOIN alla tabella temporanea (in pratica conversione da logica basata su codice a logica basata su tabella) per ottenere valori.

Questa tabella può essere riutilizzata se necessario o addirittura mantenuta.

L'aggiunta alla tabella può essere eseguita dapprima LEFT JOINing per trovare le voci nella cache mancanti.

Questo funziona sia per UDF a tabella singola che UDF scalari. Lo sto principalmente usando per UDF a valori di tabella. Esiste un aggiornamento rapido a SQL Server 2005 che dovrebbe supportare le prestazioni di UDF: sto aspettando che gli DBA li testino prima di passare alla produzione.

+0

Prima di tutto, il punto della cache è di calcolare pigramente. Popolando un tavolo con più sconfitte lo scopo. In secondo luogo, tutto questo approccio è spostare il caching dall'UDF. Perché non usare semplicemente saltare l'UDF e usare un proc? Infine, le funzioni possono essere utilizzate nelle viste, che non hanno vantaggi proc. – alyssackwan

+0

Completamente completo tutti e solo i potenziali risultati UDF. Alcuni saranno chiamati più di una volta, nessuno sarà chiamato 0 volte. Non è un cache: è un precalc. Il risparmio è direttamente misurabile dalla differenza delle chiamate UDF effettivamente fatte per popolare la tabella di ricerca. Il compromesso è l'archiviazione. –