2013-07-10 11 views
7

Mam zapytanie SQL, które trwa około 30 sekund, aby uruchomić, który zwraca 1 rekord. Funkcja używana w CROSS APPLY jest natychmiastowa po uruchomieniu z BrandId tego rekordu.CROSS APPLY różnica wydajności

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 

Jednak jeśli po prostu zmienić tabelę uzyskać BrandId od do krzyża ZASTOSOWANIA ..

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 

zapytanie teraz zajmuje tylko 2 sekundy, aby uruchomić. Gdy dołączę do dbo.Brand b ON cah.RepresentedByBrandId = b.BrandId, oczekuję, że będą takie same.

Czy ktoś może wyjaśnić, dlaczego ogromna różnica w wydajności?

UPDATE

Różnica polega na tym, ponieważ CROSS APPLY działa na całej tabeli Brand kiedy używam b.BrandId i cały stół AccountHandler kiedy używam ah.RepresentedByBrandId. Tabela AccountHandler jest znacznie mniejsza.

Spodziewałem się jednak, że CROSS APPLY uruchomi się właśnie na wynikach JOIN, które są jednym rekordem. Czy to jest możliwe, czy też tęsknię za rozumieniem CROSS APPLY?

+2

Czy inny plan wykonania nie zawiera żadnych wskazówek? –

+0

Nie jestem dobry w ich odczytywaniu, ale wygląda na to, że uruchamia się krzyżyk dla całej tabeli Brands, kiedy używam b.BrandId, a nie tylko podzbioru utworzonego przez join – Magpie

+0

Możliwe, że jestem ślepy. Ale gdzie zadeklarowano alias "cah" w drugim zapytaniu? – Devart

Odpowiedz

14

Znaleziono.

Aby wymusić krzyża stosuje się do pracy na planie sub wyników od sprzężeń, a nie na całym stole, zanim dołączy użyłem opcja (siła kolejności)

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) 

to teraz działa natychmiast i patrząc na plan wykonania funkcja jest wywoływana tylko dla jednego wyniku, a nie dla całej tabeli db.

+2

WYMAGANIE FORMY nie zawsze pomaga, musiałem użyć tabeli pośredniej do przechowywania wyników "głównej kwerendy", a następnie zastosować ją z tą funkcją. –

-1

Miałem ten sam problem i rozwiązałem go, używając ZASTOSOWANIA ZEWNĘTRZNEGO zamiast CROSS APPLY.

Powiązane problemy