Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Złożone zapytanie i dziwne zachowanie sie MySQL
Forum PHP.pl > Forum > Bazy danych > MySQL
Przemo`
Mam wykonać zapytanie:
  1. INSERT DELAYED IGNORE
  2. INTO przemo_read_history (user_id, forum_id, topic_id, post_id, post_time)
  3. SELECT DISTINCT us.user_id, 33, 11080, 80504, 1114438808
  4. FROM przemo_user_group g, przemo_auth_access aa, przemo_users us
  5. WHERE aa.forum_id = 33 AND us.user_lastvisit > 1113229208 AND (
  6.    (
  7.       us.user_active = 1
  8.       AND ug.user_pending = 0
  9.       AND ug.user_id != 2
  10.       AND us.user_id != -1
  11.       AND aa.group_id = ug.group_id
  12.       AND ug.user_id = us.user_id
  13.       AND
  14.       (
  15.          (
  16.             aa.auth_read != 0 AND aa.auth_view != 0
  17.          ) OR aa.auth_mod = 1
  18.       )
  19.    )
  20.    OR us.user_level = 1
  21. )
I problem sie pojawia gdy w którymkolwiek miejscu dodaje OR us.user_level = 1 nieważne czy jest to na koncu, czy na poczatku tego drzewa zależności i niezależnie od umieszczenia nawiasów, za każdym razem gdy to dodam zapytanie trwa kilkanaście sekund, a bez tego trwa ułamek sekundy.
Próbowalem zamiast user_level dać inną zalezność i dalej to samo
Nie wiecie co może byc powodem?
Przy tym zapytaniu dodawane jest kilkanaście wpisów a tabela ma kilka tysięcy wpisów.
Na nielicznych serwerach wyrzuca błąd zapytania SQL, juz w tej chwili nie pamiętam jaki i nie mam zapisanego, ale też powodem jest ten ostatni OR
Struktura tabeli przemo_read_history wygląda tak:
  1. user_id mediumint(8) NOT NULL DEFAULT '0',
  2. forum_id smallint(5) UNSIGNED NOT NULL DEFAULT '0',
  3. topic_id mediumint(8) UNSIGNED NOT NULL DEFAULT '0',
  4. post_id mediumint(8) UNSIGNED NOT NULL DEFAULT '0',
  5. post_time int(11) NOT NULL DEFAULT '0',
  6. PRIMARY KEY (user_id, forum_id, topic_id, post_id, post_time),
  7. KEY user_id (user_id),
  8. KEY forum_id (forum_id),
  9. KEY topic_id (topic_id)
SongoQ
Filtry ktore uzywaja bazy danych dla ORow dzialaja bardzo dlugo. Tego niestety nie przeskoczysz, algorytmy przeszukiwania nie dzialaja tak jak dla AND. Bazka jest na MySQLu, wiec masz male pole do popisu, ale np w PG moglbys napisac sobie wlasna funkcyjke ktora bys wywolywal i zobaczyl bys rezutlat. Kiedys przy testach aplikacji dla ponad 30 milionow rekordow kilka ORow spowodowalo spadek wydajnosci do kilkudziesieciu sekund. Po "dostrojeniu" zapytania (funkcje ktora mozna by powiedziec robila jako filtr) zeszlo do < 1s.
Przemo`
Dziękuje za informacje, tego sie obawiałem sad.gif
Niestety PG odpada, gdyż jest on na niewielu serwerach a chodzi tutaj o skrypt do powszechnego użytku.
Pozdrawiam
Synaps
Nie jestem do końca pewien jaki wpływ będzie to miało na performance, jendak może spróbować coś takiego.

  1. SELECT DISTINCT us.user_id, 33, 11080, 80504, 1114438808
  2. FROM przemo_user_group g, przemo_auth_access aa, przemo_users us
  3. WHERE aa.forum_id = 33 AND us.user_lastvisit > 1113229208 AND (
  4. us.user_active = 1 AND ug.user_pending = 0 AND ug.user_id != 2 AND us.user_id != -1 AND aa.group_id = ug.group_id AND ug.user_id = us.user_id AND (
  5. (
  6. aa.auth_read != 0 AND aa.auth_view != 0
  7. ) OR aa.auth_mod = 1
  8. )
  9. )
  10. UNION
  11. SELECT DISTINCT us.user_id, 33, 11080, 80504, 1114438808
  12. FROM przemo_user_group g, przemo_auth_access aa, przemo_users us
  13. WHERE aa.forum_id = 33 AND us.user_lastvisit > 1113229208 AND us.user_level = 1

Wydaje mi się, że ze względu na selektywność możesz dodać jeszcze indeks na polu us.user_level. Dawno nie bawiłem się tunningiem mysql'a jednak mam nadzieje, że to cos pomoże. Daj znać jakie będą efekty.
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.