2008-08-05 6 views
14

Czy kiedykolwiek widziałeś któryś z komunikatów o błędach?Czy kiedykolwiek napotkano zapytanie, którego SQL Server nie mógł wykonać, ponieważ odwoływał się do zbyt wielu tabel?

- SQL Server 2000

Nie można przydzielić tabelę pomocniczą dla widoku lub rozmiar funkcyjnego.
Przekroczono maksymalną liczbę tabel w zapytaniu (256).

- SQL Server 2005

Zbyt wiele nazw tabel w zapytaniu. Maksymalna dopuszczalna wartość to 256.

Jeśli tak, co zrobiłeś?

Biorąc pod uwagę? Przekonany klient, aby uprościć ich wymagania? Denormalizował bazę danych?


@ (wszyscy chcą mi odpowiedzieć na zapytanie):

  1. Nie jestem pewien, czy mogę wklejać 70 kilobajtów kodu w oknie odpowiedzi edycji.
  2. Nawet jeśli mogę to nie pomoże, ponieważ 70 kilobajtów kodu będzie zawierało 20 lub 30 widoków, które również będę musiał opublikować, ponieważ w przeciwnym razie kod będzie bez znaczenia.

Nie chcę brzmieć jakbym się przechwalał, ale problem nie leży w kwerendach. Zapytania są optymalne (lub przynajmniej prawie optymalne). Spędziłem niezliczone godziny, optymalizując je, szukając każdej kolumny i każdej tabeli, którą można usunąć. Wyobraźmy sobie raport, który ma 200 lub 300 kolumn, które muszą zostać wypełnione pojedynczą instrukcją SELECT (ponieważ tak zostało zaprojektowane kilka lat temu, kiedy był jeszcze małym raportem).

+0

Czy używasz programu SQL Server 2000 SP3? – Stu

+0

Czy mógłbyś stworzyć jakieś widoki? –

+1

Wyświetlenia nie pomogą. Tabele użyte w widokach również wliczają się do limitu. –

Odpowiedz

8

W przypadku SQL Server 2005 zalecam używanie zmiennych tabelarycznych i częściowe budowanie danych w trakcie pracy.

Aby to zrobić, utwórz zmienną tabeli, która reprezentuje ostateczny zestaw wyników, który chcesz wysłać do użytkownika.

Następnie znajdź swoją podstawową tabelę (na przykład tabelę zamówień w powyższym przykładzie) i pobierz te dane, a także trochę dodatkowych danych, które mówią tylko o jednym połączeniu (nazwa klienta, nazwa produktu). Możesz wykonać SELECT INTO, aby umieścić to bezpośrednio w zmiennej tabeli.

Stamtąd przejdź przez stół i dla każdego wiersza, wykonaj kilka małych zapytań SELECT, które pobierają wszystkie dodatkowe dane potrzebne do zestawu wyników. Wstaw je do każdej kolumny w trakcie podróży.

Po zakończeniu można następnie wykonać prosty WYBIERZ * ze zmiennej tabeli i zwrócić ten zestaw wyników użytkownikowi.

Nie mam żadnych liczb twardych, ale istnieją trzy odrębne przypadki, nad którymi pracowałem do tej pory, gdzie wykonanie tych mniejszych zapytań faktycznie zadziałało szybciej niż wykonanie jednego ogromnego kwerendy z kilkoma złączeniami.

1

Nigdy nie spotkałem się z taką sytuacją i, szczerze mówiąc, pomysł przywoływania> 256 tabel w zapytaniu napełnia mnie śmiertelnym lękiem.

Twoje pierwsze pytanie powinno prawdopodobnie brzmieć "Dlaczego tak wielu?", A zaraz po nim "jakie fragmenty informacji muszę NOT potrzebuję?" Obawiałbym się, że ilość danych zwracanych przez takie zapytanie zaczęłaby znacząco wpływać na wydajność aplikacji.

+0

Wyobraź sobie klienta, który chce zobaczyć listę (w siatce) przedmiotów w swoich sklepach wraz z naprawdę dużą ilością powiązanych informacji (np. O pierwszym zamówieniu każdego przedmiotu, o ostatnim zamówieniu, o pierwszej dostawie, o ostatniej dostawie , o klientach, którzy go kupują, o kosztach dostawy, ...). Uwierz mi, to możliwe, widziałem to. I musiałem sobie z tym poradzić. :) Tak, wpływ na wydajność może być poważny w takich sytuacjach. –

0

Chciałbym zobaczyć to zapytanie, ale wyobrażam sobie, że jest to jakiś problem z jakimś iteratorem, i chociaż nie mogę wymyślić żadnych sytuacji, w których jest to możliwe, założę się, że jest to zły przypadek/case/cursor lub mnóstwo słabo zaimplementowanych widoków.

+0

Nie ma żadnego rodzaju iteratora. Tylko jedna instrukcja SELECT. –

1

@chopeen Możesz zmienić sposób obliczania statystyk, a zamiast tego zachować osobną tabelę wszystkich statystyk dotyczących poszczególnych produktów. Po złożeniu zamówienia przechodź przez produkty i aktualizuj odpowiednie rekordy w statystykach stół. Spowoduje to przesunięcie dużej części obciążenia obliczeniowego na stronę kasy, a nie uruchomienie wszystkiego w jednym dużym zapytaniu podczas uruchamiania raportu. Oczywiście istnieją pewne statystyki, które nie będą działać w ten sposób, np. śledzenie kolejnych zakupów klientów po zakupie określonego produktu.

0

post zapytanie: D

Również czuję się jak jeden z możliwych problemów może być o ton (czytaj 200+) tabel nazwa/wartość, która mogłaby skondensowane w jednej tabeli.

1

Stało się tak przez cały czas podczas pisania raportów usług raportowania dla instalacji Dynamics CRM uruchomionych w programie SQL Server 2000. CRM ma dobrze znormalizowany schemat danych, co powoduje wiele sprzężeń. W rzeczywistości jest tam poprawka zwiększająca limit z 256 do 260: http://support.microsoft.com/kb/818406 (zawsze uważaliśmy to za świetny dowcip ze strony zespołu SQL Server).

Rozwiązaniem, do którego dąży Dillie-O, jest identyfikacja odpowiednich "podłączy" (najlepiej tych, które są używane wiele razy) i uwzględnienie ich w zmiennych tabeli temp, które następnie są używane w głównych połączeniach. To poważna PIA i często zabija wydajność. Przykro mi.

@Kevin, uwielbiam tę koszulkę - mówi wszystko :-).

0

Miałem ten sam problem ... moje środowisko programistyczne uruchamia SQL Server 2008 (widok działał dobrze), ale na produkcji (z SQL Server 2005) widok nie. Skończyło się tworzenie widoków, aby ominąć to ograniczenie, używając nowych widoków jako części zapytania w widoku, który spowodował błąd.

trochę głupie biorąc pod uwagę wykonanie logicznego jest taka sama ...

+2

To dziwne, że pomogło - o ile mi wiadomo, tabele używane w widokach liczą się do limitu. Czy korzystasz z widoków indeksowanych? –

0

miał ten sam problem w SQL Server 2005 (pracował w 2008 roku), gdy chciałem utworzyć widok. Rozwiązałem problem, tworząc procedurę przechowywaną zamiast widoku.

Powiązane problemy