Domanda

Al lavoro abbiamo due server, uno esegue un'applicazione che molte persone usano e che ha un back-end di SQL Server 2000. Sono stato libero di interrogarlo per molto tempo, ma non posso aggiungere nulla come procedure memorizzate o tabelle extra.

Questo ci ha portato ad avere un secondo SQL Server collegato al primo e io costruendo una libreria di procedure memorizzate che interrogano i dati da entrambi i lati usando un server collegato. Alcune di queste query richiedono più tempo di quello che vorrei.

Qualcuno può indicarmi alcuni buoni articoli sull'uso dei server collegati? Sono particolarmente interessato a scoprire quali dati vengono trasferiti tra i due poiché di solito la maggior parte dell'istruzione sql potrebbe essere eseguita in remoto, ma ho la sensazione che potrebbe trasferire i tavoli completi, di solito è solo un join a un piccolo finale tabella localmente.

Inoltre che cosa ho attualmente le opzioni del server collegato:

  • Compatibile con regole di confronto True
  • Accesso ai dati True
  • Rpc True
  • Rpc Out True
  • Utilizza false regole di confronto remote
  • Nome fascicolazione (vuoto)
  • Timeout connessione 0
  • Timeout query 0

Modifica

Ho pensato di aggiornare questo post e ho usato le query aperte con parametri dinamici per un po 'per migliorare le prestazioni, grazie per il suggerimento. Tuttavia, ciò può rendere le query più complicate man mano che si finisce con le stringhe. finalmente quest'estate abbiamo aggiornato SQL Server al 2008 e implementato il mirroring dei dati live. Ad essere sinceri, le query aperte si stavano avvicinando alla velocità delle query locali per i miei compiti, ma il mirroring ha sicuramente reso più facile gestire il sql.

È stato utile?

Soluzione

Consiglierei le query dinamiche in un ciclo di cursore anziché i join collegati. Questo è l'unico modo in cui sono stato in grado di replicare le prestazioni di join collegate di MS Access (almeno per singole tabelle remote)

I join regolari collegati in ms sql sono troppo inefficienti estraendo tutto specialmente nelle tabelle gigantesche.

- Vorrei sapere cosa c'è di così male nelle openquery nei loop del cursore? se fatto correttamente, non ci sono problemi di blocco.

Altri suggerimenti

Evita join con le tabelle dei server collegati.

L'uso di una denominazione in quattro parti per il join può essere utilizzato ma è più costoso. Il join potrebbe contenere criteri che possono essere utilizzati per limitare il set di dati dal server collegato e utilizzare le colonne indicizzate.

Esempio:

SELECT loc.field1, lnk.field1
FROM MyTable loc
INNER JOIN RemoteServer.Database.Schema.SomeTable lnk
  ON loc.id = lnk.id
  AND lnk.RecordDate = GETDATE()
WHERE loc.SalesDate = GETDATE()

Questa query applica anche un criterio nel join che può essere utilizzato dal server collegato prima del calcolo del join.

Il metodo raccomandato è l'uso di OPENQUERY.

Evitando il join con l'uso di OPENQUERY, il server locale invia solo la query da eseguire in remoto invece di inviare un set di ID per il join.

Utilizzare il collegamento per recuperare un set di dati ed eseguire i calcoli localmente. Utilizzare una tabella temporanea (per query ad hoc) o inserire la riga in una tabella permanente in un lavoro notturno.

L'inizio delle transazioni potrebbe non riuscire a seconda che il coordinatore delle transazioni remote sia impostato nel server apprezzato. Usarlo consumerà più risorse.

Considera anche che stai colpendo un server di produzione che esegue un'applicazione, mentre non lo specifichi, penso che sia sicuro supporre che stia usando transazioni pesanti e facendo inserimenti e aggiornamenti. Stai togliendo risorse dall'applicazione.

Il tuo scopo sembra essere l'uso dei dati a fini di reportistica. Il tuo server può essere impostato per avere un registro semplice anziché completo per renderlo più efficiente.

Eviterete inoltre che le vostre richieste vengano annullate a causa dello spostamento dei dati sul server collegato. Prestare sempre attenzione a impostare il livello di isolamento adeguato per le query e i suggerimenti per la tabella come NOLOCK.

E PER FAVORE! Non inserire mai un OPENQUERY (o qualsiasi server collegato) all'interno di un loop!

Quando si utilizzano server collegati per join come questo, è importante che il server a cui si è immediatamente connessi ("quot" local "sia quello con la maggior parte dei dati, in cui il server collegato fornisce solo un piccolo parte dei dati, altrimenti sì, estrarrà tutti i dati necessari per eseguire il join.

Le alternative includono la copia di un sottoinsieme dei dati in una tabella temporanea con tutto il lavoro svolto per snellire i risultati e qualsiasi pre-elaborazione che il server collegato può eseguire, quindi eseguire il join su " local " lato.

Potresti scoprire che puoi facilmente migliorare le prestazioni invertendo il modo in cui lo fai, connettendoti al server su cui non hai alcun controllo (dovranno creare un server collegato per te) e quindi connettendoti al tuo server tramite il link . Se hai bisogno di fare un lavoro importante con i dati in cui dovresti creare sprocs, quindi invia i dati sul tuo server e usa i tuoi sprocs lì.

In alcuni casi, ho semplicemente fatto eseguire al server collegato una creazione notturna di questo tipo di riepilogo che ha inviato al server locale, quindi il server locale ha svolto il proprio lavoro con il join.

Dolore reale

Avevamo diversi server collegati nel nostro negozio e si è rivelato essere un tale PITA .

Prima di tutto, c'erano gravi problemi di prestazioni simili a quelli che descrivi. Sono rimasto scioccato quando ho visto le statistiche I / O della rete. Nonostante tutti gli sforzi, non siamo riusciti a suggerire a SQL Server un comportamento ragionevole.

Un altro problema era che i proc memorizzati avevano questi nomi di server collegati hardcoded ovunque, senza alcun modo per sovrascriverli. Pertanto, gli sviluppatori non sono stati in grado di testare facilmente sui propri sandbox di sviluppo alcuna funzionalità che toccasse i server collegati. Questo è stato un grande ostacolo alla creazione di una suite di unit test universalmente utilizzabile.

Alla fine abbiamo abbandonato completamente i server collegati e spostato la sincronizzazione dei dati nei servizi web.

Le query che coinvolgono semi-join in un server collegato tendono a non essere molto efficienti. Potresti stare meglio usando OPENQUERY per popolare dati in una tabella temporanea locale e quindi lavorarci su da lì.

Ho scritto un'applicazione server collegato remoto in SQL 2000 un paio di anni fa e ho riscontrato gli stessi problemi di prestazioni descritti. Ho finito per riscrivere le procedure memorizzate più volte per ottenere le migliori prestazioni.

Ho usato ampiamente le tabelle temporanee. Ho scoperto che era meno costoso recuperare grandi quantità di dati remoti in una tabella temporanea, quindi unirsi ad essa, manipolarli, ecc. Unire i locali alle tabelle remote era molto lento come si designa.

La visualizzazione del piano di esecuzione e la visualizzazione del piano di esecuzione stimato tendevano ad aiutare, anche se non capivo molto di quello che stavo guardando.

Non so se esiste davvero un modo efficace per fare queste query con un server remoto perché sembra che SQL Server non possa sfruttare le sue normali ottimizzazioni quando si va contro un server collegato. Potrebbe sembrare che stai trasferendo l'intero tavolo perché in realtà è quello che sta succedendo.

Mi chiedo se uno scenario di replica potrebbe funzionare per te. Avendo i dati sul tuo server locale, dovresti essere in grado di scrivere query normali che funzioneranno come desiderato.

Non conosco nessun buon articolo a cui puntare. Mentre scrivo applicazioni più complesse di SQL Server, ho iniziato a pensare di aver bisogno di una migliore comprensione del funzionamento di SQL Server. A tal fine abbiamo acquistato la serie MS Press Inside Microsoft SQL Server 2005 a cura di Kalen Delaney qui al lavoro. Volume 1: il motore di archiviazione è sicuramente il punto di partenza, ma non ci sono arrivato molto. Poiché i miei ultimi progetti non hanno coinvolto SQL Server, il mio studio su di esso è diventato lassista.

È possibile impostare un database separato sul server anziché utilizzare un server collegato?

È un problema molto generoso, che può avere molte soluzioni. Ma come abbiamo visto molti utenti affermano di aver provato di tutto.

Ciò che ha risolto il mio problema è ...

Ho aggiornato SQL Server 2000 da SP2 a SP4 e se hai già SP4 su SQL Server 2000 allora eseguo Instcat.sql. Secondo la mia esperienza, posso assicurarti che funzionerà sicuramente, se sei esausto con tutte le altre soluzioni alternative.

Grazie, Mithalesh mithalesh.gupta@gmail.com

SQL dinamico e una funzione possono essere utilizzati per aggirare la domanda del nome con codice fisso. Ad esempio, sto provando un'implementazione in cui la funzione ufn_linkedDatabase (@purpose nvarchar (255)) con input 'cpi.cpi' (CPI scopo, impostazione predefinita sub-scopo) restituisce "[SERVER-NAME.DOMAIN.LCL, 2000]. [CPI]" nell'ambiente di produzione (dove utilizziamo un numero di porta alternativo per SQL Server, non so perché, incluso nel nome del server collegato). Quindi un comando SQL viene assemblato in @template varchar (max) con l'espressione @ {cpi.cpi} che rappresenta il server e il database collegati, quindi @workstring = REPLACE (@template, N'@{cpi.cpi} ', ...). Il modo in cui la funzione ottiene effettivamente il nome del database è separato dalle procedure: una tabella di ricerca è utile.

Problemi - fare OPENQUERY (), che probabilmente è ancora meglio almeno a meno che l'opzione del server collegato " compatibile con le regole di confronto " è impostato " true " in modo che più attività possano essere eseguite sul server collegato - importante anche su una rete veloce, e la nostra rete interna della sala server è rispettabilmente veloce - per eseguire OPENQUERY () probabilmente ho bisogno di gestire 'cpi.cpi.server' e ' cpi.cpi.database 'e' cpi.cpi.server.database 'separatamente. E potrei finire per scrivere esattamente un'applicazione usando questo design, nel qual caso è sovra-progettato. Tuttavia, ciò significa che la funzione stessa non deve essere alcun tipo di lavoro elaborato.

Lanciare hardware di rete veloce al problema potrebbe essere la risposta più economica, comunque.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top