Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> optymalizacja pewnych zapytan
AcidBurnt
post 27.12.2005, 23:21:00
Post #1





Grupa: Zarejestrowani
Postów: 215
Pomógł: 1
Dołączył: 13.04.2003
Skąd: z ławki przed blokiem

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


witam

nie za bardzo wiedzialem gdzie to wrzucic czy do php czy do baz, ostatecznie padło na bazy


mam taki kodzik w php
  1. <?php
  2.  
  3. $db -> Execute("UPDATE temida_users SET user_child = NULL");
  4. $row = $db -> Execute("SELECT user_name,user_id, user_parent, user_child FROM temida_users WHERE u
    ser_level <> 0 ORDER BY user_id"
    );
  5. foreach($row -> GetRows() as $cos){
  6. if($cos["user_parent"] != 0){
  7. $child_database = $db -> GetOne("SELECT user_child FROM temida_users WHERE user_id = '".$cos["user_parent"]."'");
  8. if(is_null($child_database)){
  9. $childs = array();
  10. }
  11. else{
  12. $childs = unserialize($child_database);
  13. }
  14. array_push($childs, $cos["user_id"]);
  15. $db -> Execute("UPDATE temida_users SET user_child = '".serialize($childs)."' WHERE user_id = '".$cos["user_parent"]."'");
  16. unset($childs);
  17. unset($child_database);
  18. unset($child);
  19. }
  20. }
  21.  
  22. ?>


kod dziala na tabeli:

  1. CREATE TABLE temida_users
  2. (
  3. user_id int8 NOT NULL DEFAULT NEXTVAL('temida_users_user_id_seq'::regclass),
  4. user_parent int8 DEFAULT 0,
  5. user_child text,
  6. }


w user_child znajduje sie zserialozowana tablica z dziecmi danego usera.

no i niestety juz przy okolo 1200 wpisach w bazie, czas dzialania tego skryptu na serwerkach nazwa.pl to ponad 100 sekund, az boje sie sprawdzac co bedzie jak bedzie tego wiece

ma ktos pomysł na zoptymalizowanie tego?


UPDATE:

przysniło mi sie conieco i taki kod:

  1. <?php
  2.  
  3. $db -> Execute("BEGIN");
  4. $db -> Execute("UPDATE temida_users SET user_child = NULL");
  5. $row = $db -> Execute("SELECT user_id, user_parent FROM temida_users WHERE user_level <> 0 ORDER BY user_id");
  6. $users = $row -> GetRows();
  7. $tree = array();
  8. foreach($users as $cos){
  9. if($cos["user_parent"] != 0){
  10. if(is_array($tree["".$cos["user_parent"].""])){
  11. array_push($tree["".$cos["user_parent"].""], $cos["user_id"]);
  12. }
  13. else{
  14. $tree["".$cos["user_parent"].""] = array();
  15. array_push($tree["".$cos["user_parent"].""], $cos["user_id"]);
  16. }
  17. }
  18. }
  19. foreach ($tree as $a => $b){
  20. $tree2[$a] =serialize($tree[$a]);
  21. }
  22. foreach ($tree2 as $a => $b){
  23. $db -> Execute("UPDATE temida_users SET user_child = '".$b."' WHERE user_id = '".$a."'");
  24. }
  25. $db -> Execute("COMMIT");
  26.  
  27. ?>


na tych samych danych czas dzialania 13 sekund. z czego 12 to wysłanie samych UPDATE do bazy, mysliCie ze da sie tutaj cos jeszcze wyciągnąc.

Ten post edytował AcidBurnt 28.12.2005, 01:14:23
Go to the top of the page
+Quote Post
DeyV
post 28.12.2005, 01:43:00
Post #2





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Ok. Super. Świetnie.

A teraz może powiesz, co chcesz osiągnąć tym kodem?
Myślę, że dzięki temu znacznie łatwiej byłoby optymalizować ten algorytm...


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
AcidBurnt
post 28.12.2005, 01:53:38
Post #3





Grupa: Zarejestrowani
Postów: 215
Pomógł: 1
Dołączył: 13.04.2003
Skąd: z ławki przed blokiem

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


eh fakt sorki,

no wiec w user_child jest tablica uzytkwoników bedacych dzeiciami danego usera..

algorytm na przebudowywac to drzewo, a wlasciwie tworzyc je odnowa w razie wystepowania jakis problemów z systemem.

wiec zbiera informacje kto jest rodzicem danego kogos, i dodaje do drzewa danego rodzica id dziecka
Go to the top of the page
+Quote Post
Jabol
post 28.12.2005, 09:12:40
Post #4





Grupa: Przyjaciele php.pl
Postów: 1 467
Pomógł: 13
Dołączył: 22.02.2003

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


No więc ja bym powiedział - zmień podejście do sprawy. Wałkowaliśmy to tutaj setki razy i naprawdę pojawiły się świetne, np. http://forum.php.pl/index.php?showtopic=4037&hl=bsp rozwiązania. Bo z tą serializajcją i porównywaniem tablic nie wyrobisz..., oj nie

Tzn. zmień system kategorii (parent - child) na inny

Ten post edytował Jabol 28.12.2005, 09:13:22
Go to the top of the page
+Quote Post
AcidBurnt
post 28.12.2005, 12:15:44
Post #5





Grupa: Zarejestrowani
Postów: 215
Pomógł: 1
Dołączył: 13.04.2003
Skąd: z ławki przed blokiem

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


tyle ze to nie maja byc kategorie, tylko zaleznosci miedzy uzytkwonikami w systemie, i praktycznie moze sie to ciagnac w nieskonczonosc w glab, nie ma ograniczenia glebokosci drzewa.
Go to the top of the page
+Quote Post
DeyV
post 28.12.2005, 16:38:15
Post #6





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Wydaje mi się jednak, że jabbol ma rację.

Co prawda rozumiem, że idea zserializowanej tablicy ma zapewne zadanie optymalizowania pobierania tych danych.
Jeśłi jednak problem sprowadza się do pobrania dzieci danego rodzica, to zwykły left join lub prosta procedura, zwracająca tablicę dzieci w żadnen sposób nie spowolni działania skryptu.
A ty unikniesz ryzyka "wystepowania jakis problemów z systemem."


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
AcidBurnt
post 28.12.2005, 16:54:54
Post #7





Grupa: Zarejestrowani
Postów: 215
Pomógł: 1
Dołączył: 13.04.2003
Skąd: z ławki przed blokiem

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


hm... chodzi o to ze system ma umozliwic proste dowolne zmiany w strukturze drzewa, np przeniesienie drzewa pod 1 userem do innego i tym podobne operacjie

EDIT

dobra wiec jak to najlepiej rozwiazac, trzymac w tabeli tylko info o user parent, i wszelkie operacjie robic posiadajac tylko ta info, czy zrobic Sobie w bazie dodatkowa tebaele zawierajaca tylko relacjie (user,parent)?

EDIT 2

chociaz wydaje mi sie ze przy koniecznosci zbudowania drzewa od poczatku calosc bedzie wymagala takiej samej liczby operajci ;/ i bedzie zajmowac ta samą ilosc czasu,

co prawda funckja przebudowania zostala napisana tylko na wszelki wypdaek, i raczej staramy sie napisac system tak zeby nie bylo takiej mozliwosci jak przeklamania w bazie, miedzy innymi dla tego wybralismy postgresa korzystamy z commit i rollback na wszelki wypadek... i chyba nie bedzie z tym prolemu

no ale lepiej miec i nie potrzebowac nic potrzebowac a nie miec

Ten post edytował AcidBurnt 28.12.2005, 17:16:23
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 20.06.2025 - 08:49