Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Propel, relacja "n do m", niska wydajność
joebezucha
post
Post #1





Grupa: Zarejestrowani
Postów: 43
Pomógł: 1
Dołączył: 23.05.2007
Skąd: Gliwice

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


Witam,

Pracuje wlaśnie nad projektem z wykorzystaniem frameworka Symfony i pojawił sie pierwszy problem. Problemem jest wydajność Propel-a.

Fragment opisu schematu bazy danych:

  1. CREATE TABLE `answer`
  2. (
  3. `id` INTEGER NOT NULL AUTO_INCREMENT,
  4. `question_id` INTEGER NOT NULL,
  5. `no` INTEGER NOT NULL,
  6. `body` TEXT NOT NULL,
  7. `scale` INTEGER,
  8. `grade` INTEGER,
  9. PRIMARY KEY (`id`),
  10. INDEX `FI_answer_1` (`question_id`),
  11. CONSTRAINT `FK_answer_1`
  12. FOREIGN KEY (`question_id`)
  13. REFERENCES `question` (`id`)
  14. ON DELETE CASCADE
  15. )Type=InnoDB;
  16.  
  17. CREATE TABLE `test`
  18. (
  19. `id` INTEGER NOT NULL AUTO_INCREMENT,
  20. `status` INTEGER NOT NULL,
  21. `test_type` INTEGER NOT NULL,
  22. `lname` VARCHAR(40) NOT NULL,
  23. `fname` VARCHAR(24) NOT NULL,
  24. `birthdate` DATE NOT NULL,
  25. `sex` CHAR NOT NULL,
  26. `school_type` INTEGER NOT NULL,
  27. `user_id` INTEGER NOT NULL,
  28. `password` VARCHAR(20),
  29. `created_at` DATETIME,
  30. `timestart` DATETIME,
  31. `timefinish` DATETIME,
  32. `ip` VARCHAR(15),
  33. PRIMARY KEY (`id`),
  34. INDEX `FI_test_1` (`user_id`),
  35. CONSTRAINT `FK_test_1`
  36. FOREIGN KEY (`user_id`)
  37. REFERENCES `user` (`id`)
  38. ON DELETE CASCADE
  39. )Type=InnoDB;
  40.  
  41. CREATE TABLE `test_answer`
  42. (
  43. `test_id` INTEGER NOT NULL,
  44. `answer_id` INTEGER NOT NULL,
  45. PRIMARY KEY (`test_id`,`answer_id`),
  46. INDEX `FI_ta_1` (`answer_id`),
  47. CONSTRAINT `FK_ta_1`
  48. FOREIGN KEY (`answer_id`)
  49. REFERENCES `answer` (`id`)
  50. ON DELETE CASCADE,
  51. CONSTRAINT `FK_ta_2`
  52. FOREIGN KEY (`test_id`)
  53. REFERENCES `test` (`id`)
  54. ON DELETE CASCADE
  55. )Type=InnoDB;


Jak widać są tu 3 tabele test, asnwer, i tabela test_answer która odpowida za relacje "n do m"

W skrypcie PHP mam:

  1. <?php
  2. $this->test = TestPeer::retrieveByPk($this->getRequestParameter('id')); // 1*
  3. $c = new Criteria();
  4. $c->setLimit(10);
  5. $test_answers = $this->test->getTestAnswersJoinAnswer($c);  // 2*
  6. foreach ($test_answers as $test_answer){
  7. $answer = $test_answer->getAnswer();
  8. }
  9. ?>

No i w tym momencie pojawił się problem z wydajością PROPELa. Czas tworzenia kolekcji $test_answers rośnie po exponencie;) przy limicie ustawionym na 200 skrypt zostaje zakończony w wyniku przekroczenia limitu czasu(60sekund). No a wszystkich odpowiedzi mam do pobrania 214.

W narzędziu WebDebug (część frameworka Symfony) widze, że wykonywane są tylko dwa zapytania do bazy:
1* pobranie testu
2* pobranie danych z tabel test_answer złączonej z answer

Czyli nie ma problemu z zapętlaniem zapytań do bazy danych.
Zresztą robie wszytsko zgodnie z instrukcją propel.phpdb.org/trac/wiki/Users/Documentation/1.2/ManyToManyRelationships

Czy Propel jest aż tak mało wydajny?(IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)

Potrzebuję pełnych danych odpowiedzi na pytania testowe do przeliczenia wyników końcowych. Mogę oczywiście obejść Propela, skorzystac bezposrednio z Creola i operować na tablicach zamiast na obiektach. No ale zastanawia mnie ta bardzo niska wydajność.

Jakieś pomysły?(IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif) (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Ten post edytował joebezucha 2.07.2007, 15:19:31
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
joebezucha
post
Post #2





Grupa: Zarejestrowani
Postów: 43
Pomógł: 1
Dołączył: 23.05.2007
Skąd: Gliwice

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


Dzięki za wysiłek pawel_k

Jeszcze dziś sprawdzę czy z uproszczeniem schematu bazy to będzie hulać jak trzeba...

Bez uproszczeń sprawdzałem wydajność w zależności od setLimit(limit)

czasy są w [ms]

limit; query time; module/action time; full time;
1; 1.99; 459; 1328;
5; 1.72; 356; 1009;
10; 3.30; 529; 1196;
20; 2.20; 1000; 1756;
40; 2.32; 3839; 4487;
80; 2.70; 12414; 13167;
160; 3.90; 46567; 47259;

Jak widać do 20 jest OK ale potem lawinowo wzrasta czas procesu ORM...

Puki co zrobiłem to troche inaczej tzn robie własne złączenie tabel i pobieram bezposrednio obiekty klasy Answer.

w akcji mam:

  1. <?php
  2. $c = new Criteria();
  3. $c->addJoin(AnswerPeer::ID, TestAnswerPeer::ANSWER_ID, Criteria::LEFT_JOIN);
  4. $c->add(TestAnswerPeer::TEST_ID, $this->getId());
  5. $this->collAnswers = AnswerPeer::doSelect($c);
  6. ?>


No i tutaj działa wszystko OK.
Wyglada na to ze problem z wydajności występuje gdy Propel pobiera obiekty TestAnswer i jednoczesnie agregowane przez nie obiekty Answer.

Moj komp:
Athlon XP 1800+
RAM 896 MB
WIN XP SP2

Dam znać jak wypadły testy z uproszczonym schematem bazy danych

Zrobilem osobny projekt ze schematem uproszczonym do tej postaci co w poscie Pawła K.

Niestety problem wydajnosci ciagle występuje.
Czasy minimalnie sie zmniejszyły pownieważ mniej danych jest pobieranych no ale wykonanie trwa i tak grubo ponad 40sekund:/

Ktoś ma jakies pomysły w czym może tkwić problem??

Paweł jakiej wersji Propela uzywasz?(IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)

Ten post edytował joebezucha 5.07.2007, 08:46:59
Go to the top of the page
+Quote Post

Posty w temacie


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 Aktualny czas: 14.10.2025 - 23:02