Mam tabelę ItemValue pełen danych na SQL 2005 Server uruchomiony w 2000 trybie zgodności, który wygląda mniej więcej tak (to zdefiniowana przez użytkownika wartości tabela):Optymalizacja SQL - zmiany planu wykonania na podstawie wartości wiązania - Dlaczego?
ID ItemCode FieldID Value
-- ---------- ------- ------
1 abc123 1 D
2 abc123 2 287.23
4 xyz789 1 A
5 xyz789 2 3782.23
6 xyz789 3 23
7 mno456 1 W
9 mno456 3 45
... and so on.
FieldID pochodzi z ItemField tabela:
ID FieldNumber DataFormatID Description ...
-- ----------- ------------ -----------
1 1 1 Weight class
2 2 4 Cost
3 3 3 Another made up description
. . x xxx
. . x xxx
. . x xxx
x 91 (we have 91 user-defined fields)
Ponieważ nie mogę PIVOT w trybie 2000, utknęliśmy budowy brzydkie zapytanie korzystając przypadkach i GROUP bY, aby uzyskać dane wyglądać jak powinien dla s ome aplikacje Legacy, który brzmi:
ItemNumber Field1 Field2 Field3 .... Field51
---------- ------ ------- ------
abc123 D 287.23 NULL
xyz789 A 3782.23 23
mno456 W NULL 45
Widać musimy tylko tę tabelę, aby pokazać wartości do 51. UDF. Oto zapytanie:
SELECT
iv.ItemNumber,
,MAX(CASE WHEN f.FieldNumber = 1 THEN iv.[Value] ELSE NULL END) [Field1]
,MAX(CASE WHEN f.FieldNumber = 2 THEN iv.[Value] ELSE NULL END) [Field2]
,MAX(CASE WHEN f.FieldNumber = 3 THEN iv.[Value] ELSE NULL END) [Field3]
...
,MAX(CASE WHEN f.FieldNumber = 51 THEN iv.[Value] ELSE NULL END) [Field51]
FROM ItemField f
LEFT JOIN ItemValue iv ON f.ID = iv.FieldID
WHERE f.FieldNumber <= 51
GROUP BY iv.ItemNumber
Gdy FieldNumber ograniczeniem jest < = 51, wykonanie planu idzie mniej więcej tak:
SELECT <== Computer Scalar <== Stream Aggregate <== Sort (Cost: 70%) <== Hash Match <== (Clustered Index Seek && Table Scan)
i to szybko! Mogę cofnąć ponad 100 000 rekordów w ciągu sekundy, co odpowiada naszym potrzebom.
Jednak gdybyśmy mieli więcej UDF i zmienić ograniczenie do niczego powyżej (tak, testowałem je jeden po drugim) lub usunąć je całkowicie, tracę sortowane w plan wykonania, a to zostaje zastąpiony całą masą bloków równoległościowości, które zbierają, dzielą i rozprowadzają strumienie, a cała sprawa jest powolna (30 sekund nawet na 1 rekord).
FieldNumber ma klastrowych niepowtarzalny indeks i jest częścią kompozytu podstawowego klucza z ID kolumnowej (wskaźnik nieklastrowanym) w ItemField tabeli. W ItemValue stołu ID i Nummer artykułu kolumny dokonać PK, a tam jest dodatkowy nieklastrowanym indeks na kolumnieNummer artykułu.
Jaki jest tego powód? Dlaczego zmiana mojego prostego ograniczenia liczby całkowitej zmienia cały plan wykonania?
A jeśli już chcesz ... co zrobiłbyś inaczej? Za kilka miesięcy planowane jest uaktualnienie SQL, ale wcześniej muszę rozwiązać ten problem.
Co zrobiłbym inaczej, nie używaj tej struktury tabeli. Znacznie lepiej jest użyć struktury z określonymi polami dla 99% potrzebnych danych, które można z góry określić, niż użyć tabeli EAV. Nawiasem mówiąc, tryb zgodności nie uniemożliwia korzystania z nowych funkcji, jest umożliwienie korzystania z funkcji, które nie są już dozwolone. Jeśli jednak tworzysz bazę danych z bazą danych 2000 z 2000 roku, najlepiej jest unikać nowych funkcji. – HLGEM