sql server dołącz / gdzie zlecenie przetwarzania
<p>po przeczytaniu <a href="https://stackoverflow.com/questions/7193533/slow-sql-query-not-sure-how-to-optimize">wolne zapytanie sql, nie jestem pewien, jak zoptymalizować</a> , pomyślałem o ogólnej wydajności zapytań. z pewnością potrzebujemy, aby wyniki pierwszej tabeli (gdy połączone są inne tabele) były możliwie jak najmniejsze przed dołączeniem (złączenia wewnętrzne dla tego pytania), aby nasze zapytania były nieco szybsze.</p><p>przykład:</p><pre><code>select * from ( select * from table1 where col = @val ) t inner join table2 on col = col2 </code></pre><p>bądź lepszy/szybszy niż:</p><pre><code>select * from table1 inner join table2 on col = col2 where table1.col = @val </code></pre><p>moja teoria jest następująca (może to nie być poprawna implementacja, próbuję zapamiętać z przeczytanej książki o sql server 2008 (msft press)):</p><ol> <li>procesor zapytań najpierw pobiera lewą tabelę (tabela1)</li> <li>dołącza do drugiej tabeli (tabela 2) i tworzy produkt kartezjański przed odfiltrowaniem niezbędnych wierszy (jeśli dotyczy)</li> <li>następnie wykonuje klauzule where, order by, group by, having z instrukcją seelct jako ostatnią.</li> </ol><p>jeśli więc w powyższym zestawieniu nr 1 tabela jest mniejsza, silnik sql ma mniej pracy przy tworzeniu produktów kartezjańskich. następnie po osiągnięciu instrukcji where masz ograniczony zestaw wyników do filtrowania w pamięci.</p><p>mógłbym być tak daleko od znaku, że to nierealne. tak jak powiedziałem, to teoria.</p><p>twoje myśli?</p><p><strong> uwaga </strong>: właśnie pomyślałem o tym pytaniu i nie miałem jeszcze okazji przeprowadzić żadnych testów.</p><p><strong> uwaga 2 </strong>: oznaczono jako sql server, ponieważ nie wiem <em> cokolwiek</em> o implementacji mysql itp. proszę poczuć w każdym razie swobodnie odpowiadać/komentować</p>
<p>logiczne przetwarzanie zapytania odbywa się na <a href="http://msdn.microsoft.com/en-us/library/ms189499.aspx"> msdn </a> (napisane przez zespół microsoft sql server, a nie firmy zewnętrzne)</p><pre><code>1. from 2. on 3. join 4. where 5. group by 6. with cube or with rollup 7. having 8. select 9. distinct 10. order by 11. top </code></pre><p>tabela pochodna podąża za tym, a następnie zapytanie zewnętrzne robi to ponownie itp. itd</p><p>jest to <strong> logiczne </strong> chociaż: nie <strong> rzeczywiste </strong>. bez względu na to, jak sql server to robi, semantyka jest honorowana <em> do litery</em>. „rzeczywisty” jest określany przez optymalizator zapytań (qo) i unikasz wspomnianego pośredniego produktu cartesion.</p><p>warto wspomnieć, że sql jest deklaratywny: mówisz „co”, a nie „jak”, jak w przypadku programowania proceduralnego/imperatywnego (java, .net). zatem powiedzenie „dzieje się to wcześniej” jest w wielu przypadkach błędne (np. założenie, że występują zwarcia lub kolejność l-do-r, gdzie)</p><p>w powyższym przypadku qo wygeneruje ten sam plan, bez względu na jego strukturę, ponieważ jest to proste zapytanie.</p><p>jednak qo opiera się na kosztach i w przypadku złożonego zapytania wygenerowanie idealnego planu może zająć 2 tygodnie. więc robi to „wystarczająco dobrze”, co tak naprawdę nie jest.</p><p>twój pierwszy przypadek może pomóc optymalizatorowi w znalezieniu lepszego planu, ponieważ logiczna kolejność przetwarzania jest inna dla 2 zapytań. ale może nie.</p><p>użyłem tej sztuczki w sql server 2000, aby uzyskać 60-krotną poprawę wydajności w zapytaniach dotyczących raportowania. ponieważ qo ulepsza wersję do wersji, staje się coraz lepszy w rozwiązywaniu tych problemów.</p><p>i wspomniana książka: istnieje spór<br> patrz so i kolejne linki: <a href="https://stackoverflow.com/q/3270338/27535">https://stackoverflow.com/q/3270338/27535</a> </p>
Ok. Znalazłem to w czym problem.


Na początku myślałem, że to problem z DataProvided, ale to nie było. Odkryłem ten sam problem w SQLServer 2000 ....


Wyszukiwanie w google dowiedziałem się czegoś o plan wykonania. Biorąc w ten sposób, że zapytania zwiększyło wydajność 50%.


Krótki życiorys tego problemu jest to, że podczas wykonywania SP kodem, DBMS ma pewne problemy z planu wykonania, a nie korzystać z indeksów ...


Lepszą odpowiedź jest w tym poście:
 [Parametr Wąchania (lub Fałszowanie) w SQL Server](https://stackoverflow.com/questions/211355/parameter-sniffing-or-spoofing-in-sql-server)


Mam nadzieję, że to Ci pomoże. Z ograniczeniem, że klauzula warunek może być „coś”, to jesteś ograniczony do skanowania całą listę i stosując warunek.


Jeśli istnieją ograniczenia dotyczące klauzuli stan, wtedy można spojrzeć na organizowanie danych do bardziej efektywnie obsługiwać zapytań.


Na przykład, przykładowy kod z „byFirstLetter” słowniku nie pomaga w ogóle z „endswith” zapytania.


Więc tak naprawdę sprowadza się do tego, co pyta chcesz zrobić przed tymi danymi.


W bazach danych, problem ten jest ciężar „optymalizator zapytań”. W typowej bazy danych, jeśli masz bazę danych bez indeksów, oczywiście każde zapytanie będzie skan tabeli. Jak dodać indeksów w tabeli, optymalizator może użyć tych danych do bardziej wyrafinowanych zapytań planuje lepiej dostać się do danych. To w istocie problem, który opisujesz.


Gdy masz bardziej konkretny podzbiór typów kwerend następnie można zrobić lepszą decyzję, co struktura jest najlepsza. Ponadto, należy wziąć pod uwagę ilość danych. Jeśli masz listę 10 elementów każdy mniej niż 100 bajtów, skan wszystko może okazać się najszybciej, co można zrobić, ponieważ masz taką małą ilość danych. Oczywiście, że nie skaluje się do elementów 1M, ale nawet sprytnych technik dostępu nosić koszt w instalacji, konserwacji (jak utrzymanie indeksu) i pamięć.


**EDIT** , na podstawie komentarza


Jeśli jest to auto Nieukończenie, jeśli dane są statyczne, a następnie posortować je i używać przeszukiwanie binarne. Nie jesteś naprawdę dzieje się szybciej niż to.


Jeśli dane są dynamiczne, a następnie zapisać go w zrównoważonym drzewie, i szukać tego. To skutecznie wyszukiwanie binarne, a to pozwala zachować dodać dane losowo.


Coś jeszcze jest jakaś specjalność na tych pojęć. To naprawdę zależy od rodzaju danych, które zabierasz powrotem. Ponieważ zbiór danych (w efekcie) tylko zbiór DataTable obiektów, można zwracać wiele różnych zestawów danych w jednym, a więc łatwiejsze, obiektu. 


Performance-mądry, jesteś bardziej prawdopodobne, aby uzyskać nieefektywność z zapytaniami niezoptymalizowanych niż z „niewłaściwym” wybór .NET konstruktu. Przynajmniej tak było moje doświadczenie. Jest to dość szerokie, ale dam ci tak ogólną odpowiedź, jak tylko mogę.

**CTE ...**

* Są niezindeksowalne (ale mogą używać istniejących indeksów na obiektach, do których istnieją odwołania)
* Nie można mieć ograniczeń
* Są zasadniczo jednorazowe `VIEW` s
* Trwać tylko do momentu uruchomienia następnego zapytania
* Może być rekurencyjny
* Nie masz dedykowanych statystyk (polegaj na statystykach dotyczących podstawowych obiektów)

**#Temp Tables ...**

* Są prawdziwe zmaterializowane tabele, które istnieją w tempdb
* Może być indeksowany
* Może mieć ograniczenia
* Trwaj w życiu obecnego POŁĄCZENIA
* Może odwoływać się do innych zapytań lub podprocedur
* Masz dedykowane statystyki generowane przez silnik

Jeśli chodzi o użycie każdego z nich, mają bardzo różne przypadki użycia.Jeśli masz bardzo duży zestaw wyników lub musisz odwołać się do niego więcej niż raz, umieść go w tabeli `#temp` .Jeśli ma być rekurencyjny, jednorazowy lub po prostu dla uproszczenia logicznego, preferowany jest `CTE` .

Ponadto należy `CTE`**nigdy nie używaj do wykonania**.Prawie nigdy nie przyspieszysz przy użyciu CTE, ponieważ znowu jest to widok jednorazowy.Możesz zrobić z nimi kilka fajnych rzeczy, ale przyspieszenie zapytania nie jest jednym z nich. druga pewnie jest dla sprawdzenia poprwanosci odpowiedzi, kucze nie pamietam dokladnie tych komend ale sprobuj skopjowac je z tej gotowej tabelki i ewentualnie cos pozmieniaj- a dokladniej t wspolrzedne pol zeby sie zgadzaly (wstaw tylko w pierwszych ramkach a reszte zlap za jeden rog i przeciagnij to ci sie skopiuje dla innych wynikow) Często jest to realizowane za pomocą [„Data Driven Subskrypcje”](https://msdn.microsoft.com/en-us/library/ms169673.aspx) , ale ta funkcja jest dostępna tylko w niektórych wersjach SQL: Enterprise i Business Intelligence, ale nie w standardzie.


Tak więc istnieje wiele twórczych obejścia. Ale nie lubię żadnego z nich, a wszystko to wymaga uczciwej trochę pracy poza SSRS.


Do obejścia widziałem to: Tworzenie subskrypcji, a następnie wyłączenie lub włączenie zadanie SQL, który wysyła subskrypcję (zidentyfikowanego przez GUID).


Tworzenie .exe .NET otoki do obsługi wysyłania wiadomości e-mail. Można go uruchomić kwerendę najpierw sprawdzić, ile zwracane są wiersze, a następnie w razie potrzeby wygenerować raport i umieścić go w wiadomości e-mail. Cóż, jeden z reaons dlaczego zajęcia zazwyczaj zawierają członków prywatnych z publicznymi pobierające / ustawiające jest dokładnie ponieważ mogą zweryfikować dane.


Jeśli masz numer niż może wynosić od 1 do 100, na pewno umieścić coś w seter, że sprawdza, a następnie może rzucić wyjątek, który jest złowionych przez kod. Powód jest prosty: jeśli nie rób tego w seter, trzeba pamiętać, że od 1 do 100 ograniczenie każdym razem, gdy go ustawić, co prowadzi do kodu duplikaty lub gdy go zapomnieć, prowadzi do nieprawidłowym stanie.


Jeśli chodzi o wydajność, jestem z Knuth tutaj:



> 
> „Powinniśmy zapomnieć o małej wydajności, powiedzmy około 97% czasu. Przedwczesna optymalizacja jest źródłem wszelkiego zła”
> 
> 
> ło panie. dobra. jeśli używasz entity framework, to wybierz wszystko, co jest w danej tabelce do zmiennej (i już masz dane 2 cache). sprawdzasz ile masz tam danych metodą count dostępną dla list. robisz tablicę dynamiczną i wrzucasz tam dane podzielone z listy. zwykły for od 0 do tego, ile zwróciło … masz kilka możliwości: 

użyć pętli for i wewnątrz if

użyć pętli while

użyć po prostu filtra listy (\_\_ne\_\_ - not equal):

<https://www.online-python.com/uqefk1lvdj> 
pod względem wydajności najlepszy jest tutaj filtr. IAM nie wiem, to jest to, czego szukasz, ale jeśli rozumiem można to zrobić:


-on sprawdzić obciążenie aktualizacja wartości QS, jeśli jej nie ma użyć ukrytego pola wprowadzania.


-pierwsze czas ładowania strony z QS, zrobić swoje normalne przetwarzanie i przechowywanie wartości QS w polu wejściowym ukrytym. 


-Jeśli nie ma QS następnie użyj ukrytej wartości wejściowej


-po odświeżenie strony, można przekierować do tej samej strony, w tym momencie można użytkownik Request.Form [], aby odzyskać pole wprowadzania ukryty, nadal załadować dane poprawnie, ale pozbyć się QS.


to miało sens w mojej głowie, nie jestem pewien, że to ma sens teraz, ale ja nie pozwolę ci zdecydować.