Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: optymalizacja pewnych zapytan
Forum PHP.pl > Forum > Bazy danych > PostgreSQL
AcidBurnt
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.
DeyV
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...
AcidBurnt
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
Jabol
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
AcidBurnt
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.
DeyV
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."
AcidBurnt
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
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.