TSQL Ominięcie 'nie jest równe'

0

Witam
Mam powiązane ze sobą relacje tak jak w załączniku. Potrzebuje sprawdzić te lokacje z tabeli Stock, które mają PalletId oraz BoxId oraz ten rekord z tabeli Pallet ma różne LocationId z tabeli Box. Tak wiem, że jest to pokręcone, ale w poniższych zapytaniach wiadomo mniej więcej o co chodzi.

Mój problem jest taki, że o ile udało mi się osiągnąć to co chcę, o tyle problem jest z wydajnością. Operacja 'nie jest równe' jest stosunkowo bardzo kosztowna. Wymyśliłem dwa zapytania - ale oba przy sprawdzaniu planu zapytania dają mi taki sam koszt.

SELECT *
from Stock s
where (Select LocationId from Pallet p where p.PalletId = s.PalletId) <> (Select LocationId from Box b where b.BoxId = s.BoxId)
SELECT *
from Stock s
inner join Pallet p on s.PalletId = p.PalletId
inner join Box b on b.BoxId = s.BoxId
where p.LocationId <> b.LocationId
1

ddl tabel, przykładowe dane i wynik to pomyślimy

BTW może być jeszcze tak

SELECT *
FROM Stock s
INNER JOIN Pallet p ON s.PalletId = p.PalletId
LEFT JOIN Box b ON b.BoxId = s.BoxId
WHERE b.LocationId IS NULL
0

Może jakiś indeks?

0

Może tak:

SELECT     
	* 
FROM       
	stock s 
	INNER JOIN pallet p ON s.palletid = p.palletid 
	INNER JOIN box b ON b.boxid = s.boxid 
	LEFT JOIN ( 
					  SELECT palletid, 
							 boxid 
					  FROM   
						pallet pp 
						INNER join box bb ON pp.locationid = bb.locationid) ex 
					ON  ex.palletid = s.palletid AND ex.boxid = s.boxid 
WHERE
	ex.palletid IS NULL
0

@a.dudek76 zakładam, że przykład, który podałeś to tylko fragment całego zapytania. Póki co nie mam pomysłu jak to przyspieszyć samą składnią (bo rozumiem, że hinty i indeksy masz odpowiednie) jedyne co mi przychodzi do głowy (choć raczej tego nie zastosujesz) to utworzenie widoku zmaterializowanego. Jeśli wiesz co to, to będziesz też wiedział czy możesz czy nie możesz zastosować takie rozwiązanie, jeżeli natomiast nie wiesz co to widok zmaterializowany to powiedz czy zakres tych danych i zapytanie, które odpalasz często się zmienia zakres danych. O co pytam np o to czy jest to select na swojego rodzaju archiwum (wyciągnięcie rozbieżności za ubiegły rok z zakresu danych, które nie są zmieniane) czy jest to zapytanie odpalane x razy dziennie w ramach normalnej pracy systemu. Jeśli ta druga opcja to zapomnij o moim poście.

0

Dziękuje wszystkim za odpowiedzi. Ten newralgiczny element tyczył się jednej z procedur. Chciałem rozwiązać problem jak najmniejszym kosztem, bez potrzeby tworzenia indeksów. Moje zapytania wg planu zapytania są tak samo kosztowne jak zapytanie @abrakadaber . Niemniej postanowiłem użyć swojego drugiego rozwiązania. @woolfik - zapytanie nie działa na danych archiwalnych.

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