mam oto takie zapytanie....

    $sql="SELECT distinct(r_id), sum(p_price) AS cena, p_catalog AS katalog, sum(r_konti) as ilosci_r, sum(lascik) as lascik,
        h_city AS miasto, p_meal_code AS wyzywienie, h_counntrypageid AS pidkraju, h_country AS kraj, h_citypageid AS pidmiasta,
        h_hotelpageid AS idhotelu,
        h_name AS hotel, h_merlin_type AS merlin, r_description AS zakwaterowanie, h_category AS standard, h_code AS kod_hotelu,
        h_id AS id_hotelu, sum(control) as suma_kontrolna
        FROM pokaz
        $dodatek_a1 $dodatek_h1
        WHERE

        $dodaj_do GROUP BY r_id, p_catalog HAVING ilosci_r>=0 AND suma_kontrolna=$s_day ";

zapytanie smiga i wszystko cacy...

lecz jak policzyc ile wynikow zwraca?? (potrzebne do stronnicowania)
ogolnie zapytanie dla okolo 300pozycji  trwa okolo 2-4 sek.. (dopuszczalne) -zwraca sirednio okolo 300 pozycji (ale oczywiscie nie jest tyle na raz wyswietlane .. bo tylko 10szt i jest zrobione stronnicowanie).
A do stronicowania trzeba niestety znac ilosc wszystkich rekordow...

ale juz policzenie tego przez ..mysql_num_rows(mysql_query($sql)) to kolejne 4sek:/ czy da sie to jakos COUNTEM policzyc -podobno szybsze

plizzzzzzzzzzzzzz

My tu gadu gadu, a dziewczyny w Ornecie nic cieplego w ustach od rana nie mialy:) <>

2

Tak się chyba nie da, count dotyczy grupy, a nie wszystkich danych, które są zwracane.
Może liczyć samodzielnie, odczytując kolejne rekordy?

3

SELECT COUNT(DISTINCT *) AS [liczba wierszy] FROM tabela;

tabela powinna dać się zastąpić podzapytaniem. Problem w tym, że taka konstrukcja wymusza dwukrotne przetworzenie tego samego zapytania. Raz, aby uzyskać wynik. Drugi raz, aby policzyć wiersze. Nie powinno to stanowić problemu dla tej ilości danych uwzgledniając wewnętrzne bufory SQL-a.

Zawsze mam rację, tylko nikt mnie nie słucha.

4 Ostatnio edytowany przez laoo/ng (2007-05-26 21:20:36)

Nie wpadłem na żaden pomysł jak zrobić to bez dwukrotnego przetworzenia podzapytania. Funkcja okienkująca załatwiłaby sprawę, ale MySQL jeszcze długo nie będzie tego miał. Chyba pobierać po jednym wierszu na raz i zliczać byłoby najsensowniej.

----
EDIT: a jednak jest rozwiązanie!
W MySQLu można "udawać" okienka na zmiennych użytkownika.

zapytanie piszesz tak:

SET @q=0; SELECT t.*, @q:=@q+1 AS cnt FROM (tu twoje zapytanie) AS t;

i dostajesz wynik z dodatkową kolumną cnt, która liczy od 1 w górę. Wystarczy przeczytać ją z ostatniego wiersza i będzie to liczba wierszy.

5 Ostatnio edytowany przez Maly_swd (2007-05-26 22:49:04)

no tak.. ale chodzi o szybkosc... wiec po to jest stronicowanie aby nie trzaskac zapytania
z 300wynikami...

a tabela w mysql ma ponad 300mb danych... wiec przy pobraniu 300zapytan w godzinach szczytu (tzn jak 20-30 osob kozysta w prawie jednym czasie) to te wyniki sa nawet po 10-15 sek..

znalazlem tez cos takiego:
$sql="
    SELECT
        FOUND_ROWS() AS `found_rows`;
";
$result = mysql_query($sql);
$myrow = mysql_fetch_assoc($result);
$row_count = $myrow['found_rows'];

echo $row_count;

ale z wynikow pomiarow szybkosci ... niestety ale prawie to samo co z num_rows:/ (mam jakiegos archaicznego mysqla)

to jak macie jakies pomysly:)

Laoo -> a jak ma sie to Twoje rozwiazanie do szybkosci:) ?  bo nie mam teraz jak przetestowac

My tu gadu gadu, a dziewczyny w Ornecie nic cieplego w ustach od rana nie mialy:) <>

6

Sprawdziłem sobie i nie trzeba robić nawet podzapytania. Poprostu dodaj do swojego zapytania kolumnę "@q:=@q+1 AS cnt", przed właściwym zapytaniem wywołaj "SET @q=0;" (albo doklej je na początku) i będziesz miał dodatkową kolumnę numerującą zwracane wiersze. Odczytanie jej z ostatniego wiersza powie Ci ile ich było. Te rozwiązanie nie zwięszka złożoności zapytania. Możesz zastosować bez obaw. Jak chcesze to możesz wykonywać tam nawet bardziej złożone obliczenia od zwiększania o jeden.

7

Przepraszam, może nie zrozumiałem pytania, ale zauważyłem, że kolega Mały robi to chyba w PHP, więc rozwiązanie nasuwa się samo:

$num_rows = mysql_num_rows($result);
Czy możecie wyjaśnić, Stirlitz, dlaczego wasz służbowy adres stirlitz@rsha.gov.de ma aliasa justas@gru.su?
Nie czytam PM. Proszę używać e-mail.

8

Mały już próbował. mysql_num_rows zwiększało czas zapytania dwukrotnie...

9

Laoo -> dziekuje bardzo, jutro cos z tym pociwicze... mam nadzieje ze bedzie ok:) .. a moze jeszcze cos przez noc wymyslisz:]

Dely ->takie rozwiazanie wlasnie mam i zapytanie chodzi 2x wolniej/...

My tu gadu gadu, a dziewczyny w Ornecie nic cieplego w ustach od rana nie mialy:) <>

10

laoo/ng napisał/a:

Sprawdziłem sobie i nie trzeba robić nawet podzapytania. Poprostu dodaj do swojego zapytania kolumnę "@q:=@q+1 AS cnt", przed właściwym zapytaniem wywołaj "SET @q=0;" (albo doklej je na początku) i będziesz miał dodatkową kolumnę numerującą zwracane wiersze. Odczytanie jej z ostatniego wiersza powie Ci ile ich było.

Mały grupuje wyniki zapytań, czy przedstawiona przez Ciebie inkrementacja jest wykonywana przed, czy po grupowaniu? Mam wrażenie, że przed, ale nie sprawdzałem.

Zawsze mam rację, tylko nikt mnie nie słucha.

11

a nie prosciej wynik zapytania przekierowac do tymczasowej tabeli z ktorej mozna:
a) szybko policzyc liczbe wierszy
b) latwo stronicowac

tylko nalezy pamietac o odtwarzaniu jej zawartosci przy jakikiejkolwiek modyfikacji orginalnych danych...

The UNIX Guru`s view of Sex:
unzip; strip; touch; finger; mount; fsck; more; yes; umount; sleep

12

Jellonek, o tym napisałem w pierwszym swoim poście.

Zawsze mam rację, tylko nikt mnie nie słucha.

13

lizard: a zdawalo mi sie ze pisales o "podzapytaniach" (choc wywod rzeczywiscie zaczales od tabeli)

ok - w kazdym razie wyglada to na najszybsze rozwiazanie, ale najmniej wygodne - bo trzeba sledzic zmiany we wszystkich zaleznych tabelach (ztcw. w gora 3).

The UNIX Guru`s view of Sex:
unzip; strip; touch; finger; mount; fsck; more; yes; umount; sleep

14

laoo/ng napisał/a:

Mały już próbował. mysql_num_rows zwiększało czas zapytania dwukrotnie...

No ale przeciez ta funkcja (to jest funkcja PHP) nie wykonuje zapytania, a operuje na resultsecie. Nie rozumiem jak moze spowalniac dwa razy...

edit: a juz rozumiem.
Maly nie robi sie mysql_num_rows(mysql_query($sql)) a:

$rs=mysql_query($sql);
$count=mysql_num_rows($rs);
while($row=mysql_fetch_xxx($rs)) { 
      tutaj robisz co chcesz z wynikami;
}

15 Ostatnio edytowany przez laoo/ng (2007-05-28 11:10:49)

Lizard: Nie podałbym tego rozwiązania, gdybym nie sprawdził:

mysql> set @q=0; select distinct c1, sum(c0), count(*), @q:=@q+1 from test0 group by c1;
Query OK, 0 rows affected 
 
+----+---------+----------+----------+
| c1 | sum(c0) | count(*) | @q:=@q+1 |
+----+---------+----------+----------+
| a  | 13      |        3 |        1 |
| b  | 7       |        2 |        2 |
| c  | 18      |        3 |        3 |
| d  | 17      |        2 |        4 |
+----+---------+----------+----------+
4 rows in set

jellonek: wiem, że mój hack nie jest przenośny i taki fuj, bo nie deklaratywny, ale zdefiniuj proszę prostotę i szybkość rozwiązania, bo ciekawi mnie dowód tego, że zastosowanie tymczasowej tabeli jest szybsze i prostsze (używając archaicznego mysqla nawet bez triggerów)

lewis: To pozamiatałeś.  :D

16

Ja pozamiatałem wcześniej. Nie wpadło mi tylko do głowy, że aby użyć num_rows ktoś wpadnie na pomysł żeby drugi razy wykonywać zapytanie :)

Czy możecie wyjaśnić, Stirlitz, dlaczego wasz służbowy adres stirlitz@rsha.gov.de ma aliasa justas@gru.su?
Nie czytam PM. Proszę używać e-mail.

17

:D

no tez sie nie spodziewalem ;)
laoo - przeciez tu nie o przenosnosc chodzilo ;) a chak fajny :)

The UNIX Guru`s view of Sex:
unzip; strip; touch; finger; mount; fsck; more; yes; umount; sleep

18

dely napisał/a:

Ja pozamiatałem wcześniej.

To zmień sobie tytuł z Kierownika na Sprzątaczkę zamieszania. ;)

He, he, Mały popełnił tak podręcznikowy błąd, że tylko dwóch na to zwróciło uwagę, a reszta usilnie się głowiła OCB z autorem tegoż posta na czela, a co!? :D

Zawsze mam rację, tylko nikt mnie nie słucha.

19

Ale jakie kody powymyślali, to też się chwali!

Czy możecie wyjaśnić, Stirlitz, dlaczego wasz służbowy adres stirlitz@rsha.gov.de ma aliasa justas@gru.su?
Nie czytam PM. Proszę używać e-mail.

20

I tak w ramce się nie mieszczą.

Zawsze mam rację, tylko nikt mnie nie słucha.

21

no to od poczatku... tamto zapytabie co podalem to mialo byc do liczenia ile jest rekordow...
a pozniej wykonywalem juz zapytanie z limitem np 10,20 i pobieralem czesc wierszy przez mysql_fetch_array

w skrajnych wypadkach bylo to 2x tyle czasu;] a srednio o okolo 20% wolniejsze

.. wiem iz moge pobran wszystko przez petle, ktora zaproponowal Lewis.. i pozniej w petli wypluc czesc tablicy,...

ogolnie pytam o to czy to mysql_num_rows da sie jakos inaczej zrobic...
tzn najpierw biore zapytanie z limitem ... a pozniej .. no wlasnie;) myslalem ze jest jakas sztuczka;D

My tu gadu gadu, a dziewczyny w Ornecie nic cieplego w ustach od rana nie mialy:) <>

22

Jeśli potrzebujesz zrobić to w ten dziwny sposób, to jellonek jednak ma racje. Robisz tymczasową (TEMPORARY) tabelę z kolumnami takimi jakie wyciągasz, potem INSERT ... SELECT ... do tej tabeli i potem robisz co chcesz na tej tymczasowej tabeli bo tam są tylko te wiersze, które potrzebujeszm czyli pójdzie szybko - liczysz je sobie i potem wyciągasz. Nie powinno być strasznie wolne, raczej do skrajnego przypadku nie dojdzie (większość pracy robiona jest wewnątrz bazy a wyniki wyciągane są tylko raz, co jest dużym plusem, bo przetoczenie wszystkich tych wierszy do php też trochę kosztuje).
Tabela zostanie automatycznie zdropowana przy zamknięciu połączenia (i nie będzie kolidowała z innymi połączeniami)

23

laoo napisał/a:

Tabela zostanie automatycznie zdropowana przy zamknięciu połączenia (i nie będzie kolidowała z innymi połączeniami)

przy polaczeniu typu "persistent" nie koniecznie tak szybko zostanie zdropowana, a i nie bardzo widze sens dropowac - jesli kluczem ma byc szybkosc to aktualizowalbym ją tylko w przypadku nastąpienia zmian w tabelach od ktorych zalezy...

The UNIX Guru`s view of Sex:
unzip; strip; touch; finger; mount; fsck; more; yes; umount; sleep

24 Ostatnio edytowany przez laoo/ng (2007-05-29 11:27:53)

To już zależy od szczegółów, bo zerknąwszy na zapytanie można zauważyć, że jest parametryzowane kilkoma zmiennymi (zresztą trochę w sposób jak nie powinno się tego robić, bo patrząc na kod zapytania nie wiadomo co dokładnie ono robi. Np przez zmienne $dodatek_a1 i $dodatek_h1 zapytanie może, o zgrozo, joinować podstawową tabelę z różnymi tabelami!) i jeśli wartości tych zmiennych różnią się w sąsiednich zapytaniach, to i zawartość wynikowej tabeli może być zupełnie inna i może bardziej opłacać się budować ją od nowa. A jeśli będą dwa różna zapytania z różnymi parametrami w dwóch równoległych połączeniach (czego nie można wykluczyć przy interfejsach webowych), to i tabele muszą być osobne, żeby ustrzec się nieprzewidywalnych błędów.

25

tez to zauwazylem i tez ciarki mi po plecach biegaja jak widze takie zapytanie...

The UNIX Guru`s view of Sex:
unzip; strip; touch; finger; mount; fsck; more; yes; umount; sleep