it-swarm.it

Implicazioni sulle prestazioni dell'uso di OPENQUERY in una vista

Si prega di vedere questo domanda su StackOverflow:

Sto usando un EasySoft ODBC per collegare un'istanza di SQL Server 2008 R2 Express a Interbase e ho qualche difficoltà con il recupero dei metadati dal server remoto. Guardando in rete i principali suggerimenti tutti menzionano l'utilizzo di OPENQUERY invece della sintassi del server collegato in quattro parti.

PER ESEMPIO. Il mio attuale approccio (problematico) è ...

CREATE VIEW [LIVE].[vwPRDETS]
AS

SELECT *
FROM [LBLIVE]...[PRDETS] WITH (NOLOCK)

Ma su alcuni tavoli viene visualizzato l'errore quando si chiama la vista ...

Messaggio 7353, livello 16, stato 1, riga 1 Il OLE provider DB "MSDASQL" per il server collegato "LBLIVE" ha fornito metadati incoerenti. Durante l'esecuzione è stata fornita una colonna aggiuntiva che non è stata trovata durante la compilazione tempo.

Inoltre, alcune viste che non riesco nemmeno a creare perché ottengo il seguente ...

Messaggio 7315, livello 16, stato 1, riga 1 Il OLE provider DB "MSDASQL" per il server collegato "LBLIVE" contiene più tabelle che corrispondono al nome "" SYSDBA "." AUDIT_LBABKP "".

Anche se c'è solo una delle tabelle menzionate.

L'approccio alternativo alla ricerca in rete sembra essere più simile a ...

SELECT *
FROM OPENQUERY(<linked sevrer>, 'SELECT <column list> FROM MyTable')

Quindi, la mia domanda è: se uso OPENQUERY nella definizione della mia vista, SQL Server sarà in grado di ottimizzare l'SQL risultante inviato a Interbase? O non c'è davvero molta differenza tra i due approcci?

È un argomento trasversale e mi piacerebbe un POV di un dba.

15
Rich Andrews

Sommario

Lascia che il server collegato faccia il più possibile.
È impossibile per SQL Server ottimizzare una query su un server collegato, anche un altro SQL Server

Lungo

Il fattore chiave è dove viene eseguita la query.

In questo caso, è un SELEZIONALE banale, quindi tutte le righe di una tabella verranno inviate lungo il filo. Non importa.

Quando aggiungi JOIN e WHERE, può importare. Si desidera che SQL Server consenta al server collegato di eseguire il maggior numero di filtri possibile per ridurre la dimensione dei dati provenienti dalla rete.

Ad esempio, il secondo caso qui dovrebbe essere più efficiente.

SELECT *
FROM OPENQUERY(<linked server>, 
            'SELECT <column list> FROM MyTable') T1
     JOIN
     SomeLocalTable T2 ON ...
WHERE T1.foo = 'bar'

SELECT *
FROM OPENQUERY(<linked server>, 
           'SELECT <column list> FROM MyTable WHERE foo = ''bar''')
     JOIN
     SomeLocalTable T2 ON ...

Una limitazione di OPENQUERY è che non puoi parametrizzare: quindi hai bisogno di SQL dinamico per aggiungere clausole WHERE ecc.

Le prestazioni dei server collegati possono essere influenzate da sp_serveroption . Le impostazioni collation compatible dice tutto

Se questa opzione è impostata su true, SQL Server presuppone che tutti i caratteri nel server collegato siano compatibili con il server locale, per quanto riguarda il set di caratteri e la sequenza di confronto (o l'ordinamento). Ciò consente a SQL Server di inviare confronti su colonne di caratteri al provider. Se questa opzione non è impostata, SQL Server valuta sempre i confronti nelle colonne di caratteri a livello locale.

Ossia, cerca di non consentire a SQL Server di elaborare i dati localmente.

Nota: sul mio foo = 'bar' 2 ° esempio sopra, il filtro viene inviato al server collegato perché è solo una costante di stringa a SQL Server. La vera clausola WHERE nel primo esempio può essere inviata o meno in remoto.

Infine, ho anche scoperto che mettere in scena i dati in una tabella temporanea e unirli su tabelle locali è spesso meglio che collegarli direttamente all'OPENQUERY.

20
gbn