2013-07-10 14 views
7

Ho una query SQL che richiede circa 30 secondi per eseguire il record restituito 1. La funzione utilizzata in CROSS APPLY è istantanea quando viene eseguita con BrandId di questo record.CROSS APPLY Differenza di prestazioni

SELECT 
    b.BrandId, 
    b.Name, 
    ah.Type, 
    c.ContactEmails, 
    c.ContactNumbers, 
    c.ContactLinks 
FROM 
    @IdsToFilterBy ids 
JOIN dbo.AccountHandler ah ON ah.AccountHandlerId = ids.Id 
JOIN dbo.Brand b ON ah.RepresentedByBrandId = b.BrandId 
CROSS APPLY dbo.[fn_GetBrandContactDetails](b.BrandId) AS c 

Tuttavia, se mi limito a cambiare il tavolo ho la brandid dal per la CROCE APPLICARE ..

SELECT 
    b.BrandId, 
    b.Name, 
    ah.Type, 
    c.ContactEmails, 
    c.ContactNumbers, 
    c.ContactLinks 
FROM 
    @IdsToFilterBy ids 
JOIN dbo.AccountHandler ah ON ah.AccountHandlerId = ids.Id 
JOIN dbo.Brand b ON ah.RepresentedByBrandId = b.BrandId 
CROSS APPLY dbo.[fn_GetBrandContactDetails](ah.RepresentedByBrandId) AS c <-- change here 

la query ora vogliono solo 2 secondi per l'esecuzione. Mentre mi unisco allo dbo.Brand b ON cah.RepresentedByBrandId = b.BrandId mi aspetterei che fossero uguali.

Qualcuno può spiegare perché l'enorme differenza di prestazioni?

UPDATE

La differenza è perché la croce Apply è in esecuzione su tutto il tavolo di marca quando uso b.BrandId e l'intera tabella AccountHandler quando uso ah.RepresentedByBrandId. La tabella AccountHandler è notevolmente più piccola.

Tuttavia mi aspettavo che il CROSS APPLY si esegua solo sui risultati dei JOINs, ovvero 1 record. E 'possibile o mi è mancato capire CROSS APPLY?

+2

il diverso piano di esecuzione non fornisce alcun suggerimento? –

+0

Non sono bravo a leggerli ma sembra che esegua la croce per l'intera tabella Marche quando uso b.BrandId e non solo il sottoinsieme creato dal join – Magpie

+0

Possibile che io sia cieco. Ma dove ha dichiarato l'alias 'cah' nella seconda query? – Devart

risposta

14

Trovato.

per forzare il CROSS si applicano per l'esecuzione sul sub serie di risultati dalla join e non su tutto il tavolo prima i join ho usato OPTION (FORCE ORDER)

SELECT 
    b.BrandId, 
    b.Name, 
    ah.Type, 
    c.ContactEmails, 
    c.ContactNumbers, 
    c.ContactLinks 
FROM 
    @IdsToFilterBy ids 
JOIN dbo.AccountHandler ah ON ah.AccountHandlerId = ids.Id 
JOIN dbo.Brand b ON ah.RepresentedByBrandId = b.BrandId 
CROSS APPLY dbo.[fn_GetBrandContactDetails](b.BrandId) AS c 
OPTION (FORCE ORDER) 

Questo ora funziona istantaneamente e guardando il piano di esecuzione viene chiamato per il solo risultato e non per l'intera tabella db.

+2

L'ORDINE DI FORZA non sempre aiuta, ho dovuto usare una tabella intermedia per archiviare i risultati della "query principale" e poi incrociarla con la funzione. –

-1

Ho avuto lo stesso problema e l'ho risolto utilizzando APPLICAZIONI ESTERNE anziché APPLICAZIONI CROSS.

Problemi correlati