Chciałbym Cię zapytać o Twoją opinię, jeśli chodzi o wdrożenie filtrowanego formularza wyszukiwania. Wyobraźmy sobie następujący przypadek:
- 1 Duży stół z dużą ilością kolumn
- Ważne może być powiedzenie, że ten SQL Server
Musisz zaimplementować formularz do przeszukiwania danych w tej tabeli, aw tym formularzu będziesz mieć kilka pól wyboru, które pozwolą Ci zminimalizować to wyszukiwanie.
Teraz moje pytanie brzmi, który z poniższych powinien być najlepszym sposobem na wdrożenie wyszukiwania?
Utwórz procedurę składowaną z zapytaniem w środku. Ta procedura składowana sprawdzi, czy parametry są podane przez aplikację, aw przypadku, gdy nie zostaną one podane, w kwerendzie zostanie wstawiony znak zastępczy.
Utwórz zapytanie dynamiczne, które jest budowane zgodnie z danymi podanymi przez aplikację.
Pytam o to, ponieważ wiem, że SQL Server tworzy plan wykonania po utworzeniu procedury przechowywanej, aby zoptymalizować jej wydajność, ale czy tworząc dynamiczne zapytanie wewnątrz procedury przechowywanej, poświęcimy optymalizację uzyskaną przez plan wykonania?
Proszę, powiedz mi, jakie byłoby najlepsze podejście w twoim przekonaniu.
Odpowiedzi:
Możesz przyjrzeć się odpowiedzi na to podobne pytanie tutaj: /programming/11329823/add-where-clauses-to-sql-dynamically-programmatically
Odkryliśmy, że SPROC, który przyjmuje kilka opcjonalnych parametrów i implementuje taki filtr:
zbuforuje pierwszy plan wykonania, z którym jest uruchamiany (np.
@optionalParam1 = 'Hello World', @optionalParam2 = NULL
), ale następnie wykona nieszczęśliwie, jeśli przekażemy mu inny zestaw parametrów opcjonalnych (np@optionalParam1 = NULL, @optionalParam2 = 42
.). (I oczywiście zależy nam na wydajności planu buforowanego, więc nieWITH RECOMPILE
ma go)Wyjątkiem jest tutaj to, że jeśli w zapytaniu jest co najmniej jeden filtr OBOWIĄZKOWY, który jest WYSOCE selektywny i odpowiednio zindeksowany, oprócz parametrów opcjonalnych, to powyższy PROC będzie działał dobrze.
Jednakże, jeśli WSZYSTKIE filtry są opcjonalne, dość okropną prawdą jest to, że sparametryzowany dynamiczny sql faktycznie działa lepiej (chyba że napiszesz N! Różne statyczne PROCS dla każdej permutacji parametrów opcjonalnych).
Dynamiczny SQL, taki jak poniżej, utworzy i buforuje inny plan dla każdej permutacji parametrów zapytania, ale przynajmniej każdy plan będzie „dostosowany” do konkretnego zapytania (nie ma znaczenia, czy jest to PROC, czy Adhoc SQL - ponieważ dopóki są sparametryzowane, będą buforowane)
Stąd moja preferencja dla:
itp. Nie ma znaczenia, czy przekażemy nadmiarowe parametry do sp_executesql - są one ignorowane. Warto zauważyć, że ORM, takie jak Linq2SQL i EF, używają sparametryzowanego dynamicznego sql w podobny sposób.
źródło
Zacznij od tego, co uważasz za łatwiejsze do wdrożenia (tak sądzę, opcja 2). Następnie zmierz wydajność rzeczywistych danych. Optymalizację można rozpocząć tylko w razie potrzeby, a nie wcześniej.
Nawiasem mówiąc, w zależności od stopnia złożoności filtrów wyszukiwania, zadanie może nie zostać łatwo rozwiązane bez dynamicznego SQL. Nawet jeśli korzystasz z procedury składowanej, najprawdopodobniej nie zwiększy to wydajności, jak już podejrzewasz. Z drugiej strony, jeśli to pomaga, istnieje kilka rodzajów wskazówek (patrz http://www.simple-talk.com/sql/performance/controlling-execution-plans-with-hints/ ), które można dodać do kodu SQL kwerenda, dynamiczna lub nie, aby pomóc serwerowi SQL zoptymalizować plan wykonania.
źródło