Thread View: pl.comp.objects
8 messages
8 total messages
Started by Marek Wywiał
Fri, 21 Apr 2006 12:10
wydajność GenericObject
Author: Marek Wywiał
Date: Fri, 21 Apr 2006 12:10
Date: Fri, 21 Apr 2006 12:10
29 lines
1990 bytes
1990 bytes
Witam. Jestem początkujący w obiektach ale staram się używać. Mam taki problem. Chce wyświetlić listę towarów (sql -> php4 -> html). 1. Do inicjalizacji towaru używam klasy Produkt dziedziczącej po GenericObject 2. Towary ładowane są do/przez Kolekcję implementującą leniwą konkretyzację 3. Iterując Kolekcję wyciągam z każdego Produktu potrzebne mi w tym momencie właściwości. Dla bazy danych wygląda to jako seria zapytań typu SELECT * FROM towar WHERE id='<ID>'; Wolałbym aby było to jedno zapytanie: SELECT * FROM towar WHERE id IN (<ID>, <ID>, <ID>) I nie wiem jak to zaimplementować, aby nie zaburzyć obiektowości w moim programie. Proszę o wskazówki (nazwę wzorca, standardowego obiektu) google niewiele mi pomogło (zapewne znam zbyt mało słów kluczy by odszukać interesujące mnie informacje)
Re: wydajność GenericObject
Author: Seweryn Habdank-Wojewódzki
Date: Fri, 21 Apr 2006 12:44
Date: Fri, 21 Apr 2006 12:44
15 lines
1144 bytes
1144 bytes
Witam Marek Wywiał wrote: > Proszę o wskazówki (nazwę wzorca, standardowego obiektu) A wzorzec Visitor nie będzie dobry? Wie całkiem rozumiem czy problem jest po stronie SQL, czy w programie. Pozdrawiam. -- |\/\/| Seweryn Habdank-Wojewódzki `\/\/
Re: wydajność GenericObject
Author: Marek Wywiał
Date: Fri, 21 Apr 2006 13:38
Date: Fri, 21 Apr 2006 13:38
23 lines
2335 bytes
2335 bytes
Visitor uzyskuje dostęp do danych obiektu, już po jego stworzeniu (danego obiektu) więc w optymalizacji zapytań nie pomoże. Chodzi mi bardziej o coś w rodzaju BulkMode(??) GenericObject aby tworzenie grupy obiektów nie odbywało się przy pomocy osobnych zapytań (jeden select na każdy obiekt) tylko jedno zapytanie zwracające dane dla wielu obiektów naraz, a następnie stworzenie i zwrócenie takiej załadowanej już kolekcji. Mogę to napisać po swojemu, ale wolałbym nie wymyślać koła od nowa i popełniać przy tym błędy innych :) W praktyce wygląda to tak, że wejście w kategorię produktów na stronie (zawiera 2-10 produktów) jest szybkie i nie obciaża serwera. Natomiast w przypadku generowaniu spersonalizowanego cennika ( ponad 400 pozycji) trwa to długo, i obciąża maszynę na tyle mocno, że kolejne zapytania (lub co gorsza cenniki w tym czasie) przekraczają czas wykonania php. Ominąłem to stosując prosty Cache na plikach (dla cenników). Ale ciekaw jestem czy jest znane rozwiązanie programistyczne tego problemu na poziomie tworzenia obiektów.
Re: wydajność GenericObject
Author: Seweryn Habdank-Wojewódzki
Date: Fri, 21 Apr 2006 14:39
Date: Fri, 21 Apr 2006 14:39
45 lines
2859 bytes
2859 bytes
Witam Marek Wywiał wrote: > Chodzi mi bardziej o coś w rodzaju BulkMode(??) GenericObject > aby tworzenie grupy obiektów nie odbywało się przy pomocy osobnych > zapytań (jeden select na każdy obiekt) tylko jedno zapytanie > zwracające dane dla wielu obiektów naraz, a następnie stworzenie i > zwrócenie takiej załadowanej już kolekcji. To już coraz bardziej nie kapuje. > W praktyce wygląda to tak, że wejście w kategorię produktów na > stronie (zawiera 2-10 produktów) jest szybkie i nie obciaża serwera. > > Natomiast w przypadku generowaniu spersonalizowanego cennika ( ponad > 400 pozycji) trwa to długo, i obciąża maszynę na tyle mocno, że > kolejne zapytania (lub co gorsza cenniki w tym czasie) przekraczają > czas wykonania php. A gdybyś po prostu konstruował w locie zapytanie, poprzez formowanie "stringa". Czyli poprostu jeśli tych ID jest dużo, to grupujesz je po 10, 15 ładujesz do konstruowanego wlocie stringa (który jest zapytaniem SQL) i to wysyłasz do bazy danych. Ladowanie do stringa 400 numerów ID też jest chyba przyciężkawe, więc lepiej zrobić jakieś takie rozwiązanie pośrednie. Czyli pytanie w blokach po X numerów ID. Coś takiego: masz listę ID_list i w niej ID'ki. Ja tniesz na K grup po N elementów i ostatnia może być albo trochę większa niż N albo mniejsza niż N, to zależy jaką strategią uznajesz czy pozwalasz do ostatniej dołączyć restówkę, czy resztówka jest osobno. Można to zrobić inteligentnie i jeśli restówka jest > N/2 to jest osobno jeśli mniejsza to dołączasz ją do ostatnije grupy N elementowej. Potem tworzysz automatycznie zapytania SQL z tymi ID'kami z pociętej listy i wio każde zapytanie jest relatywnie krótkie i jest ich relatywnie niedużo. Pozdrawiam. -- |\/\/| Seweryn Habdank-Wojewódzki `\/\/
Re: wydajnosc GenericObject
Author: Marek Wywial
Date: Fri, 21 Apr 2006 16:06
Date: Fri, 21 Apr 2006 16:06
59 lines
2800 bytes
2800 bytes
Chyba popelnilem skrót myslowy i nie wytlumaczylem wszystkiego :)
teraz mam tak:
// lista ID produktów, które maja zostac stworzone i wyswietlone
$arProdId = array( 1, 2, 3, 4, 5, 6, 7, 8) // pobrane selectem z bazy
//i aby otrzymac wszystkie te produky wykonuje:
$kolekcjaProduktow = Collection::createCollection($arProdId);
kolekcja wykonuje:
class Collection {
...
// po otrzymaniu tablicy z ID'ami
function createCollection($arProdId) {
// iteruje ta tablice
foreach($arProdId as $intProdId) {
// i dla kazdego ID tworzy odpowiedni obiekt produkt
$this->_object[$id] = new ProductObject($id);
}
return $this->_objects;
}
...
}
[1] Konstruktor ProductObject wykonuje:
..
__construct($id) {
$this->_fields = $db->GetAll("SELECT * FROM products WHERE
id='$id'");
}
i wlasnie stad bierze sie seria zapytan do bazy
Pomyslem moze byc nadpisanie konstruktora w ProductObject aby jako
dane wejsciowe mógl pobrac dane pobrane selectem zbiorczym
wczesniej i zamiast selecta swojego uzyc te dane ? ale czy to jest
madre ?
czyli
$arProdukty = $db->getAll("SELECT * from produkty where id in(1,2,3,4);
foreach($arProdukty as $arProdukt) {
$arrayProdukty[] = new ProduktObject($arProdukt);
}
a ProductObject:
__construct($data) {
if(is_Array($data)) {
$this->_fields = $data;
} else {
$this->_fields = $db->getAll("SELECT * from produkty WHERE
id='$data'");
}
a moze juz bredze po 5 dniach pracy :)
pozdrawiam,
Re: wydajnosc GenericObject
Author: Seweryn Habdank-Wojewódzki
Date: Fri, 21 Apr 2006 16:28
Date: Fri, 21 Apr 2006 16:28
29 lines
1949 bytes
1949 bytes
Witam
Marek Wywial wrote:
> [1] Konstruktor ProductObject wykonuje:
> ..
> __construct($id) {
> $this->_fields = $db->GetAll("SELECT * FROM products WHERE
> id='$id'");
> }
Tego się spodziewałem. I dlatego napisałem o czytaniu paczek.
Podejdż paczkowo do tego zadania. Napisz sobie taki pod kontener z którego
będziesz budował elementy. Niech sam konstruktor nie robi select.
Rozbiłbym tworzenie obiektu od pociągania danych z bazy. Ciągnij dane z bazy w
postaci bloku, a potem blok zamieniaj na paczkę obiektów. Nie wiem jak w PHP
rozróżnia się rekordy, czyli jeśli wsadzisz ich kilka so selecta i potem
musisz je pociąć na kawałki nie tylko na pola, ale na recordy. Chyba żle też
będzie mieć selecta wszystkiego na raz, bo jak będzie tego 1000 (czy ileś tam
(musisz sprawdzić eksperymentalnie), to ten select też cię zawali.
Pozdrawiam.
--
|\/\/| Seweryn Habdank-Wojewódzki
`\/\/
Re: wydajnosc GenericObject
Author: Marek Wywiał
Date: Mon, 24 Apr 2006 11:20
Date: Mon, 24 Apr 2006 11:20
6 lines
1561 bytes
1561 bytes
Tak właśnie myślałem, ale obawiałem się, że naruszę hermetyzację obiektów (Produkt) jeżeli inny obiekt będzie pobierał dla niego dane do konstruktora. Dziękuje serdecznie i pozdrawiam.
Re: wydajnosc GenericObject
Author: Seweryn Habdank-Wojewódzki
Date: Mon, 24 Apr 2006 11:37
Date: Mon, 24 Apr 2006 11:37
44 lines
2226 bytes
2226 bytes
Witam Marek Wywiał wrote: > ale obawiałem się, że naruszę hermetyzację obiektów (Produkt) > jeżeli inny obiekt będzie pobierał dla niego dane do konstruktora. EEE. Nie kapuje, czemu. Tak działają parsery XML. Przykładzik: <plik> <blok> <dane>dane_1</dane> <dane>dane_2</dane> <dane>dane_3</dane> <dane>dane_4</dane> </blok> <blok> <dane>dane_1</dane> <dane>dane_2</dane> <dane>dane_3</dane> <dane>dane_4</dane> </blok> <blok> <dane>dane_1</dane> <dane>dane_2</dane> <dane>dane_3</dane> <dane>dane_4</dane> </blok> </plik> Jeżeli "blok" jest blokiem to parsowanie "blok" zawiera parsowania obiektów "dane" i parsowanie "dane" przekazujesz parserowi "dane" a nie "blok" parsuje "dane". U Ciebie po prostu będzie poziom pośredniości będziesz miał plik = cała lista (nie pobierany jednym ciągiem bo będziesz miał paskudnego selecta), tylko dzielisz na kawałki. Wydaje mi się, że to jest rozsądne. A w strukturze klas nic nie powinno się zmiecić tylko dojdzie ci kilka klas obsługujących bloki danych. Pozdrawiam. -- |\/\/| Seweryn Habdank-Wojewódzki `\/\/
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads