Jaki jest główny cel korzystania z aplikacji CROSS APPLY ?
Przeczytałem (niejasno przez posty w Internecie), które cross apply
mogą być bardziej wydajne przy wybieraniu dużych zestawów danych, jeśli partycjonujesz. (Przychodzi mi na myśl stronicowanie)
Wiem również, że CROSS APPLY
nie wymaga UDF jako prawej tabeli.
W większości INNER JOIN
zapytań (relacje jeden do wielu) mogłem przepisać je na potrzeby używania CROSS APPLY
, ale zawsze dają mi one równoważne plany wykonania.
Czy ktoś może mi podać dobry przykład, kiedy CROSS APPLY
robi różnicę w tych przypadkach, w których również INNER JOIN
będzie działać?
Edytować:
Oto prosty przykład, w którym plany wykonania są dokładnie takie same. (Pokaż mi, gdzie się różnią i gdzie cross apply
jest szybszy / bardziej wydajny)
create table Company (
companyId int identity(1,1)
, companyName varchar(100)
, zipcode varchar(10)
, constraint PK_Company primary key (companyId)
)
GO
create table Person (
personId int identity(1,1)
, personName varchar(100)
, companyId int
, constraint FK_Person_CompanyId foreign key (companyId) references dbo.Company(companyId)
, constraint PK_Person primary key (personId)
)
GO
insert Company
select 'ABC Company', '19808' union
select 'XYZ Company', '08534' union
select '123 Company', '10016'
insert Person
select 'Alan', 1 union
select 'Bobby', 1 union
select 'Chris', 1 union
select 'Xavier', 2 union
select 'Yoshi', 2 union
select 'Zambrano', 2 union
select 'Player 1', 3 union
select 'Player 2', 3 union
select 'Player 3', 3
/* using CROSS APPLY */
select *
from Person p
cross apply (
select *
from Company c
where p.companyid = c.companyId
) Czip
/* the equivalent query using INNER JOIN */
select *
from Person p
inner join Company c on p.companyid = c.companyId
źródło
CROSS APPLY
ma swoje oczywiste zastosowanie, pozwalając na zależność zestawu od innego (w przeciwieństwie doJOIN
operatora), ale nie jest to bez kosztów: zachowuje się jak funkcja, która działa na każdym elemencie lewego zestawu, więc w SQL Server to znaczy zawsze wykonujLoop Join
, co prawie nigdy nie jest najlepszym sposobem łączenia zestawów. Więc używaj,APPLY
kiedy potrzebujesz, ale nie nadużywaj goJOIN
.Odpowiedzi:
Zobacz artykuł na moim blogu, aby uzyskać szczegółowe porównanie wydajności:
INNER JOIN
vs.CROSS APPLY
CROSS APPLY
działa lepiej na rzeczach, które nie mają prostegoJOIN
stanu.Ten wybiera
3
ostatnie rekordyt2
dla każdego rekordu zt1
:Nie można go łatwo sformułować z
INNER JOIN
warunkiem.Prawdopodobnie możesz zrobić coś takiego za pomocą
CTE
funkcji okna i okna:, ale jest to mniej czytelne i prawdopodobnie mniej wydajne.
Aktualizacja:
Właśnie sprawdziłem.
master
jest tabelą zawierającą20,000,000
rekordy zPRIMARY KEY
włączonymid
.To zapytanie:
działa przez prawie
30
sekundy, podczas gdy ten:jest natychmiastowy.
źródło
TVF
zINNER JOIN
?CROSS APPLY
, zapytał, kiedy wybraćINNER JOIN
, kiedy to też zadziała.lateral join
SQL standardowym (ANSI)cross apply
czasami pozwala ci robić rzeczy, z którymi nie możesz zrobićinner join
.Przykład (błąd składniowy):
Jest to błąd składniowy , ponieważ w połączeniu z
inner join
funkcjami tabel może przyjmować tylko zmienne lub stałe jako parametry. (Tj. Parametr funkcji tabeli nie może zależeć od kolumny innej tabeli).Jednak:
To jest legalne.
Edycja: lub alternatywnie krótsza składnia: (autor: ErikE)
Edytować:
Uwaga: Informix 12.10 xC2 + ma boczne tabele pochodne, a Postgresql (9.3+) ma boczne podkwerendy, których można użyć w podobny sposób.
źródło
SELECT
potrzebne wewnątrzCROSS APPLY
. SpróbujCROSS APPLY dbo.myTableFun(O.name) F
.Rozważ, że masz dwie tabele.
STÓŁ MASTER
TABELA SZCZEGÓŁÓW
Istnieje wiele sytuacji, w których trzeba wymienić
INNER JOIN
zCROSS APPLY
.1. Połącz dwie tabele na podstawie
TOP n
wynikówZastanów się, czy musimy wybrać
Id
iName
odMaster
i ostatnie dwie daty dla każdejId
zDetails table
.Powyższe zapytanie generuje następujący wynik.
Zobacz, wygenerował wyniki dla dwóch ostatnich dat z dwiema ostatnimi datami,
Id
a następnie dołączył te rekordy tylko w zewnętrznym zapytaniu włączonymId
, co jest błędne. Powinno to zwracać zarównoIds
1, jak i 2, ale zwróciło tylko 1, ponieważ 1 ma dwie ostatnie daty. Aby to osiągnąć, musimy użyćCROSS APPLY
.i tworzy następujący wynik.
Oto jak to działa. Kwerenda wewnątrz
CROSS APPLY
może odwoływać się do zewnętrznej tabeli, gdzieINNER JOIN
nie może tego zrobić (generuje błąd kompilacji). Po znalezieniu dwóch ostatnich dat łączenie odbywa się wewnątrz,CROSS APPLY
tjWHERE M.ID=D.ID
.2. Kiedy potrzebujemy
INNER JOIN
funkcjonalności za pomocą funkcji.CROSS APPLY
może być użyty jako zamiennik,INNER JOIN
kiedy musimy uzyskać wynik zMaster
tabeli ifunction
.A oto funkcja
który wygenerował następujący wynik
DODATKOWA KORZYŚĆ ZASTOSOWANIA KRZYŻOWEGO
APPLY
może być stosowany jako zamiennikUNPIVOT
. AlboCROSS APPLY
alboOUTER APPLY
można stosować tutaj, które są wymienne.Rozważ, że masz poniższą tabelę (o nazwie
MYTABLE
).Zapytanie jest poniżej.
co przynosi wynik
źródło
Wydaje mi się, że CROSS APPLY może wypełnić pewną lukę podczas pracy z polami obliczeniowymi w złożonych / zagnieżdżonych zapytaniach i uczynić je prostszymi i bardziej czytelnymi.
Prosty przykład: masz DoB i chcesz przedstawić wiele pól związanych z wiekiem, które będą również opierać się na innych źródłach danych (takich jak zatrudnienie), takich jak Age, AgeGroup, AgeAtHiring, MinimumRetirementDate itp. Do wykorzystania w aplikacji użytkownika końcowego (Na przykład tabele przestawne programu Excel).
Opcje są ograniczone i rzadko eleganckie:
Podkwerendy JOIN nie mogą wprowadzać nowych wartości w zbiorze danych na podstawie danych w kwerendzie nadrzędnym (musi stać samodzielnie).
UDF są schludne, ale powolne, ponieważ mają tendencję do zapobiegania równoległym operacjom. A bycie odrębnym bytem może być dobrą (mniej kodu) lub złą (gdzie jest kod) rzeczą.
Tabele połączeń Czasami mogą działać, ale wkrótce dołączasz do zapytań z tonami UNII. Wielki bałagan.
Utwórz kolejny widok jednego celu, zakładając, że twoje obliczenia nie wymagają danych uzyskanych w połowie twojego głównego zapytania.
Tabele pośredniczące. Tak ... to zwykle działa, a często jest to dobra opcja, ponieważ mogą być indeksowane i szybkie, ale wydajność może również spaść ze względu na to, że instrukcje UPDATE nie są równoległe i nie pozwalają na kaskadowe formuły (ponowne użycie wyników) w celu aktualizacji kilku pól w to samo oświadczenie. A czasem wolisz robić rzeczy za jednym razem.
Zagnieżdżanie zapytań. Tak, w dowolnym momencie możesz umieścić nawias w całym zapytaniu i użyć go jako podzapytania, na którym możesz manipulować danymi źródłowymi i polami obliczeniowymi. Ale możesz to zrobić tylko tyle, zanim stanie się brzydka. Bardzo brzydki.
Powtarzający się kod. Jaka jest największa wartość 3 długich instrukcji (CASE ... ELSE ... END)? To będzie czytelne!
Przegapiłem coś? Prawdopodobnie więc skomentuj. Ale hej, APLIKACJA KRZYŻOWA jest jak wybawienie w takich sytuacjach: wystarczy dodać prosty
CROSS APPLY (select tbl.value + 1 as someFormula) as crossTbl
i voila! Twoje nowe pole jest teraz gotowe do użycia praktycznie tak, jak zawsze było w danych źródłowych.Wartości wprowadzone za pomocą aplikacji CROSS APPLY mogą ...
CROSS APPLY (select crossTbl.someFormula + 1 as someMoreFormula) as crossTbl2
Dang, nic nie mogą zrobić!
źródło
Cross Apply działa również dobrze z polem XML. Jeśli chcesz wybrać wartości węzłów w połączeniu z innymi polami.
Na przykład, jeśli masz tabelę zawierającą trochę xml
Za pomocą zapytania
Zwróci wynik
źródło
Odpowiedź na to pytanie jest już bardzo dobra pod względem technicznym, ale pozwólcie, że podam konkretny przykład tego, jak jest niezwykle przydatna:
Powiedzmy, że masz dwie tabele: Klient i Zamówienie. Klienci mają wiele zamówień.
Chcę utworzyć widok, który poda mi szczegółowe informacje o klientach i ostatnim złożonym przez nich zamówieniu. Z JOINS wymagałoby to samodzielnego łączenia i agregacji, co nie jest ładne. Ale dzięki Cross Apply jest to bardzo łatwe:
źródło
Zastosuj krzyżowo można zastosować do zastąpienia podzapytań, w których potrzebna jest kolumna podzapytania
podzapytanie
tutaj nie będę mógł wybrać kolumn tabeli firmowej, więc używając krzyżowania
źródło
Chyba powinna to być czytelność;)
Aplikacja KRZYŻOWA będzie w pewnym sensie wyjątkowa dla osób czytających, aby powiedzieć im, że używany jest UDF, który zostanie zastosowany do każdego wiersza z tabeli po lewej stronie.
Oczywiście istnieją inne ograniczenia, w których KRZYŻ APLIKACJA jest lepiej używany niż DOŁĄCZ, które inni przyjaciele napisali powyżej.
źródło
Oto artykuł, który wyjaśnia to wszystko, z ich różnicą wydajności i wykorzystaniem w stosunku do JOINS.
SQL Server ZASTOSUJ KRZYŻ i ZEWNĘTRZNIE ZASTOSUJ przez POŁĄCZENIA
Jak zasugerowano w tym artykule, nie ma różnicy w wydajności między nimi w przypadku normalnych operacji łączenia (WEWNĘTRZNE I KRZYŻOWE).
Różnica w użyciu pojawia się, gdy trzeba wykonać takie zapytanie:
To znaczy, kiedy musisz odnosić się do funkcji. Nie można tego zrobić za pomocą INNER JOIN, co dałoby błąd „Nie można powiązać wieloczęściowego identyfikatora„ D.DepartmentID ”.” Tutaj wartość jest przekazywana do funkcji podczas odczytu każdego wiersza. Brzmi dla mnie fajnie. :)
źródło
Cóż, nie jestem pewien, czy to kwalifikuje się jako powód do zastosowania krzyżowania w porównaniu z łączeniem wewnętrznym, ale na to pytanie odpowiedziano mi w poście na forum za pomocą krzyżowania, więc nie jestem pewien, czy istnieje równoważna metoda przy użyciu łączenia wewnętrznego:
JAK POCZĄTEK
KONIEC
źródło
Istotą operatora APPLY jest umożliwienie korelacji między lewą i prawą stroną operatora w klauzuli FROM.
W przeciwieństwie do JOIN korelacja między danymi wejściowymi jest niedozwolona.
Mówiąc o korelacji w operatorze APPLY, mam na myśli po prawej stronie możemy umieścić:
Oba mogą zwracać wiele kolumn i wierszy.
źródło
To może stare pytanie, ale nadal uwielbiam moc aplikacji CROSS APPLY, która upraszcza ponowne użycie logiki i zapewnia mechanizm „łączenia łańcuchów” wyników.
Poniżej przedstawiłem skrzypce SQL, która pokazuje prosty przykład użycia aplikacji CROSS APPLY do wykonywania złożonych operacji logicznych na zbiorze danych, bez bałaganu. Nie jest trudno ekstrapolować stąd bardziej złożone obliczenia.
http://sqlfiddle.com/#!3/23862/2
źródło
Podczas gdy większość zapytań, które wykorzystują CROSS APPLY, można przepisać za pomocą INNER JOIN, CROSS APPLY może dać lepszy plan wykonania i lepszą wydajność, ponieważ może ograniczyć zestaw dołączania jeszcze przed przyłączeniem.
Skradziony stąd
źródło