Mam podwójne zapytanie o samo łączenie, w którym wydajność jest poważnie pogorszona po zamianie wartości wyszukiwania.Wydajność zapytania SQL ulega pogorszeniu W zależności od kolejności wartości wyszukiwania
-- 500,000 i/o & 500ms execution
select
fooA.ID
, fooB.ID
from
foo AS fooA
INNER JOIN bar AS barA ON fooA.barID = barA.barID
INNER JOIN foo AS fooB ON fooA.fooID = fooB.fooID -- self join
INNER JOIN bar AS barB ON fooB.barID = barB.barID
where
barA.value = 'xyz'
AND barB.value = '60'
-- 5,000 i/o & 5ms execution
select
fooA.ID
, fooB.ID
from
foo AS fooA
INNER JOIN bar AS barA ON fooA.barID = barA.barID
INNER JOIN foo AS fooB ON fooA.fooID = fooB.fooID -- self join
INNER JOIN bar AS barB ON fooB.barID = barB.barID
where
barA.value = '60'
AND barB.value = 'xyz'
- Wartość "xyz" znajduje się na liście 150000 razy w "bar" tabeli.
- Wartość "60" jest wyświetlana 500 razy w tabeli "słupkowej".
- Plany kwerend są takie same, z tym że najbardziej wewnętrzna pętla zwraca 150 000 wierszy lub 500 wierszy, w zależności od tego, która wartość wyszukiwania jest wymieniona jako pierwsza.
- Wykonywane wyszukiwania szukają indeksów nieklastrowych.
- Statystyki zostały zaktualizowane na obu tabelach przy użyciu FULLSCAN.
Dlaczego optymalizator zapytań SQL nie identyfikuje poprawnie, że w obu przypadkach najbardziej wewnętrzną częścią planu kwerendy powinna być ta z najmniejszą liczbą wierszy?
Kryteria, które ograniczają liczbę wierszy w zapytaniu, najczęściej są pierwsze. Jest to ogólna zasada. – JonH
Możliwa odpowiedź: parametryzacja zapytania, sniffowanie parametrów i ponowne użycie planu. –
Czy można utworzyć klucze podstawowe ids na tabelach foo i bar? –