Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Złożone zapytanie i dziwne zachowanie sie MySQL, Gdy dodam trzecią zależność OR muli SQL
Przemo`
post
Post #1





Grupa: Zarejestrowani
Postów: 26
Pomógł: 0
Dołączył: 15.05.2004
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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)


Ten post edytował Przemo` 25.04.2005, 18:51:28
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 3)
SongoQ
post
Post #2





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
Przemo`
post
Post #3





Grupa: Zarejestrowani
Postów: 26
Pomógł: 0
Dołączył: 15.05.2004
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Dziękuje za informacje, tego sie obawiałem (IMG:http://forum.php.pl/style_emoticons/default/sad.gif)
Niestety PG odpada, gdyż jest on na niewielu serwerach a chodzi tutaj o skrypt do powszechnego użytku.
Pozdrawiam
Go to the top of the page
+Quote Post
Synaps
post
Post #4





Grupa: Zarejestrowani
Postów: 103
Pomógł: 0
Dołączył: 1.12.2003
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


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.

Ten post edytował Synaps 27.04.2005, 07:59:26
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 23:49