OR w warunku JOINa - optymalizacja

0

Witam.

Mam problem z jedną funkcjonalnościa w ERPie którego uzywam.

Po analizie doszedłem do tego że problem leży w warunku jednego z JOINów a własciwie w tym że jest w nim użyty OR

coś w tym stylu:

INNER JOIN nz__finanse fin2 ON ( 
  fin1.nzf_id <> fin2.nzf_id 
  AND 
  ( 
    spfin.nzs_iddlugu = fin2.nzf_id 
    OR 
    spfin.nzs_idsplaty = fin2.nzf_id 
  ) 
) 
OR 
( 
  fin1.nzf_id = fin2.nzf_id 
  AND 
  spfin.nzs_iddlugu = fin2.nzf_id 
  AND 
  spfin.nzs_idsplaty IS NULL 
)

jeżeli zostawię 1 lub 2 warunek zapytanie działa dosć szybko, przy alternatywie dwóch warunków wykonuje się bardzo długo.

Moje pytanie do Was:
czy istnieje jakiś sposób mogący pomóc w tym przypadku?

Oczywiście modyfikacja zapytania odpada, mam na myśli indeksy, statystyki, plany itp.

Z góry dziękuję.

0

Zacząłbym od przebudowy indeksów i aktualizacji statystyk.

0

Te kroki juz poczynione.

Tuning advisor zaproponował kilka indeksów - dodałem.

0

efekt?

0

Brak efektu stąd post na forum ;) (te rzeczy porobiłem przed napisaniem)

0

dodawanie indeksów posiłkując się tylko TA to trochę strzelanie na ślepo... Skoro nie możesz zmieniać problematycznego zapytania, to pozostaje chyba tylko kontakt z producentem ERP-a

0

Ja bym pokombinowała. Wrzuciła bym cały ten inner join w with i dopiero zrobiła bym joina z with'em. Ciekawa jestem co na to @Marcin.Miga albo @woolfik ;)

0

Ogólnie to powinieneś pokazać plany zapytania, które masz dla wersji z ORem, jak i dla wersjia z query1 i query2. Bo tak to wróżenie z fusów. Niemniej jednak 2 techniczne pomysły.

#1 : nz__finanse można spartycjonować po NZF_ID. Nie wiem jednak czy to ma sens, bo wiem nic o dystrybucji danych i tego jak inne zapytania wykorzystują tę tabelę i na ile zmieni się plan wykonania. Partycje powinny być dużo mniejsze niż cała tabelka, to może plan zapytania w wersji z iteracją po partycjach będzie lepszy.

#2 : Jeśli z SPFIN nie wyciągasz zbyt dużo informacji, to może index na (nzs_iddlugu, nzs_idsplaty) będzie na tyle mały w porównaniu do całej tabeli, że silnik będzie preferował skanowanie indeksu, a nie tabeli.

0

Ja bym zrobił JOIN na fin2.nzf_id IN (spfin.nzs_iddlugu, spfin.nzs_idsplaty). to załatwia 1 warunek i pół drugego. resztę dałbym do WHERE

0

Przede wszystkich ustaw kolejność wyrażeń w warunku zaczynając od tego najbardziej prawdopdoobnego i najmniej obciązającego bazę. W przypadku warunku or, gdy pierwsze wyrażenie jest true kolejne nie będą musiały być sprawdzane.

0

No cóż, teoretycznie się da. Forcing query plans. Tylko pewnie sporo mordęgi z tym będzie. Najpierw zmanipulować sensowny plan poprzez przeredagowanie query, potem spróbować go gwałcić hintami, na koniec zaprogramować plan przez sp_create_plan_guide. A praktycznie to nie wiem, nie próbowałem.

1

Jeśli nie można zmienić zapytania, a dodanie indexów i hintów nie pomogło to moje pytanie jest takie czy z tego: nz__finanse można zrobić widok zmaterializowany lub przerzucić zawartość tego do tabeli tymczasowej?
Z bardziej hardcorowych rozwiązań (nie ruszając oczywiście zapytania) można przygotować odpowiednie partycjonowanie i te "problematyczne" tabele przerzucić np na ssd.
Ewentualnie z explaina możesz wyrzucić tego zbiorczego OR'a i spróbować rozbić na na dwa zapytania spięte unionem ale to niestety jest zmiana zapytania.
Ciężko coś więcej powiedzieć bez faktycznego selecta, zbioru danych i planu zapytania.

1 użytkowników online, w tym zalogowanych: 0, gości: 1