Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [SQL] Optymalizacja widoku
Forum PHP.pl > Forum > Przedszkole
xyxy
Witam,
Chce troche zoptymalizowac widok. Poniżej podaje część kodu.

  1. CREATE OR REPLACE FORCE VIEW SA.VW_COTR_PL
  2. (
  3. ID_U,
  4. ID_TT,
  5. WIN,
  6. WINVERSION
  7. )
  8. AS
  9. SELECT DISTINCT
  10. ID_U,
  11. ID_TT,
  12. (SELECT DISTINCT VALUE
  13. FROM ihs.vw_x_PL_hardware
  14. WHERE description = 'Operating System'
  15. AND time_received =
  16. (SELECT MAX (time_received)
  17. FROM ihs.vw_x_PL_hardware
  18. WHERE VALUE = vw.VALUE AND ID_TT = vw.ID_TT)
  19. AND ID_TT = vw.ID_TT
  20. AND ID_U = vw.ID_U
  21. AND row_id = vw.row_id)
  22. AS WIN,
  23.  
  24. (SELECT DISTINCT VALUE
  25. FROM ihs.vw_x_PL_hardware
  26. WHERE description = 'WIN Version'
  27. AND time_received =
  28. (SELECT MAX (time_received)
  29. FROM ihs.vw_x_PL_hardware
  30. WHERE VALUE = vw.VALUE AND ID_TT = vw.ID_TT)
  31. AND ID_TT = vw.ID_TT
  32. AND ID_U = vw.ID_U
  33. AND row_id = vw.row_id)
  34. AS WINversion
  35.  
  36. FROM ihs.vw_x_PL_hardware vw
  37. WHERE time_received = (SELECT MAX (time_received)
  38. FROM ihs.vw_x_PL_hardware vw2
  39. WHERE vw.ID_TT = vw2.ID_TT AND vw.ID_U = vw2.ID_U
  40. )
  41. AND VALUE IS NOT NULL
  42. ORDER BY ID_U, ID_TT, WIN;


Mam takie pytanie, posiadam kolo 10 takich bloków w tym kodzie:

  1. (SELECT DISTINCT VALUE
  2. FROM ihs.vw_x_PL_hardware
  3. WHERE description = 'WIN Version'
  4. AND time_received =
  5. (SELECT MAX (time_received)
  6. FROM ihs.vw_x_PL_hardware
  7. WHERE VALUE = vw.VALUE AND ID_TT = vw.ID_TT)
  8. AND ID_TT = vw.ID_TT
  9. AND ID_U = vw.ID_U
  10. AND row_id = vw.row_id)
  11. AS WINversion


różnią się tylko "description" i na końcu "AS something". Da się to jakoś skrócić, żeby nie trzeba było tak co chwile powtarzać tego selecta? Czym więcej takich selectów, tym wolniej mi się ten widok otwiera...
Noidea
Rozumiem, ze chcesz zachować strukturę kolumn w widoku taka, jaka jest. W takim razie pozostaje optymalizowanie tych drobnych SELECTów.
Na początek uszereguj warunki w WHERE od najbardziej zawężających. Czyli jeśli masz 1 000 000 rekordów, description = 'WIN Version' robi ci z tego 100 000 rekordów, a row_id = vw.row_id 100, to row_id = vw.row_id ma się znaleźć przed description = 'WIN Version'

Poza tym nie jestem pewien, czy
  1. (SELECT MAX (time_received)
  2. FROM ihs.vw_x_PL_hardware
  3. WHERE VALUE = vw.VALUE AND ID_TT = vw.ID_TT)

nie wykonuje ci się dla dla każdego wiersza zapytania SELECT DISTINCT VALUE (...), pomimo tego, że nie ma z tym zapytaniem nic wspólnego (ma z tym głównym SELECTEm). Masz przez to 3-krotne zagnieżdżenie SELECTA na tej samej tabeli.

Najlepiej odpal sobie profiler zapytań i sprawdź gdzie najwięcej czasu tracisz. MySQL na przykład ma EXPLAIN oraz http://dev.mysql.com/tech-resources/articl...y-profiler.html i pewnie jakieś profilery firm trzecich. Profiler pokaże ci też, czy nie zapomniałeś gdzieś indeksu założyć.
xyxy
ok, za chwile się za to zabiorę, uporzdkuje te warunki where. Głównie rozchodziło mi się, czy da się jakoś scalić te dwa bloki z selectami (jakimiś join'ami albo jakoś):

  1. (SELECT DISTINCT VALUE
  2. FROM ihs.vw_x_PL_hardware
  3. WHERE description = 'Operating System'
  4. AND time_received =
  5. (SELECT MAX (time_received)
  6. FROM ihs.vw_x_PL_hardware
  7. WHERE VALUE = vw.VALUE AND ID_TT = vw.ID_TT)
  8. AND ID_TT = vw.ID_TT
  9. AND ID_U = vw.ID_U
  10. AND row_id = vw.row_id)
  11. AS WIN,
  12.  
  13. (SELECT DISTINCT VALUE
  14. FROM ihs.vw_x_PL_hardware
  15. WHERE description = 'WIN Version'
  16. AND time_received =
  17. (SELECT MAX (time_received)
  18. FROM ihs.vw_x_PL_hardware
  19. WHERE VALUE = vw.VALUE AND ID_TT = vw.ID_TT)
  20. AND ID_TT = vw.ID_TT
  21. AND ID_U = vw.ID_U
  22. AND row_id = vw.row_id)
  23. AS WINversion


P.S. jak to przerobić, żeby selecty były podwójnie zagnieżdżone, a nie tak jak teraz potrójnie; jak się pozbyć tego:
  1. SELECT MAX (time_received)
  2. FROM ihs.vw_x_PL_hardware
  3. WHERE VALUE = vw.VALUE AND ID_TT = vw.ID_TT


da się to tylko raz zdefiniować wcześniej? Tak średnio znam się na SQLu, ale jakas wiedzę tam mam...
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.