Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php][mysql] kolejkowanie do wyswietlania zapytań
Forum PHP.pl > Forum > Bazy danych > MySQL
orzeleagle
witam,
potrzebuje pomocy, ogólnie plik wygląda tak:

  1.  
  2. <?php
  3. require "polaczenie_z_baza.php";
  4. polaczenie_z_baza(); // połączenie z bazą
  5.  
  6.  
  7. /* zad 4 */
  8. $a1 = mysql_query("SELECT STDDEV_POP(author_publications) FROM
  9. (SELECT COUNT(t1.id_autora) AS author_publications, t1.id_autora FROM tab_lacz1 t1, tytul t
  10. WHERE
  11. t.rok_wydania>1981 AND
  12. t.rok_wydania<1985 AND
  13. t.id_tytulu = t1.id_tytulu
  14. GROUP BY t1.id_autora) A");
  15. $a1 = mysql_fetch_assoc($a1);
  16.  
  17. $a2 = mysql_query("SELECT STDDEV_POP(author_publications) FROM
  18. (SELECT COUNT(t1.id_autora) AS author_publications, t1.id_autora FROM tab_lacz1 t1, tytul t
  19. WHERE
  20. t.rok_wydania>1981 AND
  21. t.rok_wydania<1990 AND
  22. t.id_tytulu = t1.id_tytulu
  23. GROUP BY t1.id_autora) A");
  24. $a2 = mysql_fetch_assoc($a2);
  25.  
  26. /* i tak dalej masa zapytań
  27.   ..........................
  28.   ..........................
  29.   ..........................
  30.   ..........................
  31.   ..........................
  32. */
  33.  
  34.  
  35. /* i tutaj mam duża tabelkę w której wyświetlam wynik z tych wszystkich zapytań */
  36.  
  37. <table class="textwhite" align="center" border="1">
  38. <tbody><tr>
  39. <td>Standard deviation: publication/author</td>
  40. <td>'.$a1['STDDEV_POP(author_publications)'].'</td>
  41. <td>'.$a2['STDDEV_POP(author_publications)'].'</td>
  42. <td>'.$a3['STDDEV_POP(author_publications)'].'</td>
  43. <td>'.$a4['STDDEV_POP(author_publications)'].'</td>
  44. <td>'.$a5['STDDEV_POP(author_publications)'].'</td>
  45. <td>'.$a6['STDDEV_POP(author_publications)'].'</td>
  46. <td>'.$a7['STDDEV_POP(author_publications)'].'</td>
  47. </tr>
  48. </tbody></table>
  49.  


i jest tak, że strasznie dużo czasu potrzeba na wczytanie tych wszystkich danych. W tym kodzie potrzebuje pomocy z tym żeby te dane wczytywany się pojedynczo ale dynamicznie, czyli na początku pokazuje się jeden wynik, zaraz kolejny i tak dalej aż załaduje się cała tabela.

Czy jest ktoś wstanie pomóc?
markonix
A nie można pobrać raz wszystkiego w przedziale OD i DO?
trueblue
Masz pozakładane indeksy na rok_wydania oraz id_tytulu?
I czy na pewno dobrze liczysz odchylenie? Jakie odchylenie otrzymujesz obliczając je z jednej wartości?
orzeleagle
zapytanie są dobrze, tzn tak mają być, chodzi mi jedynie o to żeby nie wczytywany się wszystkie na raz tylko pojedynczo i pojedynczo gdy się załadują wyświetlały.
nospor
A moze zamiast wymyslac kosmiczne rozwiazania, warto troche przymyslec te zapytania czy oby na pewno sa optymalne? Bo to, ze zwracaja co chcesz, nie znaczy ze sa poprawne.

Moze zacznij od EXPLAIN
mmmmmmm
1. Musisz mieć 3 indeksy (to znacznie przyspieszy):
- tytul.id_autora
- tab_lacz.id_autora
- tytul.rok_wydania
2. Użyj JOIN - to równiez powinno przyspieszyć.
3. Bierz wszystko na raz - lepiej jest wykonać raz, a nie 12 razy.
Zapytanie powinno wyglądać mniej więcej tak:
  1. SELECT
  2. STDDEV_POP(author_publications1) o1,
  3. STDDEV_POP(author_publications2) o2,
  4. STDDEV_POP(author_publications3) o3, ...
  5. FROM
  6. (SELECT
  7. t1.id_autora,
  8. COUNT(case when t.rok_wydania>1981 AND t.rok_wydania<1985 then t1.id_autora end) AS author_publications1,
  9. COUNT(case when t.rok_wydania>1981 AND t.rok_wydania<1990 then t1.id_autora end) AS author_publications2,
  10. COUNT(case when t.rok_wydania>1981 AND t.rok_wydania<1995 then t1.id_autora end) AS author_publications3, ...
  11. FROM tab_lacz1 t1 JOIN tytul t ON t.id_tytulu = t1.id_tytulu
  12. WHERE
  13. t.rok_wydania>[Minimalny rok] AND
  14. t.rok_wydania<[Maksymalny rok]
  15. GROUP BY t1.id_autora) A
orzeleagle
Cytat(mmmmmmm @ 23.01.2018, 21:22:16 ) *
1. Musisz mieć 3 indeksy (to znacznie przyspieszy):
- tytul.id_autora
- tab_lacz.id_autora
- tytul.rok_wydania
2. Użyj JOIN - to równiez powinno przyspieszyć.
3. Bierz wszystko na raz - lepiej jest wykonać raz, a nie 12 razy.
Zapytanie powinno wyglądać mniej więcej tak:
  1. SELECT
  2. STDDEV_POP(author_publications1) o1,
  3. STDDEV_POP(author_publications2) o2,
  4. STDDEV_POP(author_publications3) o3, ...
  5. FROM
  6. (SELECT
  7. t1.id_autora,
  8. COUNT(case when t.rok_wydania>1981 AND t.rok_wydania<1985 then t1.id_autora end) AS author_publications1,
  9. COUNT(case when t.rok_wydania>1981 AND t.rok_wydania<1990 then t1.id_autora end) AS author_publications2,
  10. COUNT(case when t.rok_wydania>1981 AND t.rok_wydania<1995 then t1.id_autora end) AS author_publications3, ...
  11. FROM tab_lacz1 t1 JOIN tytul t ON t.id_tytulu = t1.id_tytulu
  12. WHERE
  13. t.rok_wydania>[Minimalny rok] AND
  14. t.rok_wydania<[Maksymalny rok]
  15. GROUP BY t1.id_autora) A



to jest moje index.php

http://wklej.org/id/3352840/txt/

a w wyswietleniu wyglada tak:

https://ibb.co/dbnCww

mógłbyś mi to tak przerobić jak napisałeś w poście albo zacząć trochę żebym mógł analogicznie zrobićquestionmark.gif


bump
nospor
Cytat
bump
Moze zamiast takich bump to odnioslbys sie do wszystkich odpowiedzi, ktore dostales? Ot z tak zwyklej przyzwoitosci, ze ktos poswiecil swoj czas by ci pomoc choc nie musial.
Pilsener
Podłącze się, bo może komuś się przyda:
  1. FROM tab_lacz1 t1, tytul t
- coś takiego nie powinno być w ogóle dopuszczalne w mysql, to tworzy iloczyn tabel, czyli jak masz w jednej 100 rekordów a w drugiej 1000 to w wyniku będzie 100 000 rekordów.
Kolejna rzecz: używanie zapytań SELECT bez klauzuli LIMIT. Jest to złe, ponieważ zawsze wybieramy całą tabelę co natychmiast zabije performance kiedy tylko liczba danych wzrośnie. Gdy używa się ORMa (np. Doctrine) można sobie ustawić to automatycznie (np. jeśli nie ma klauzuli limit to z automatu jest 999).
Następna sprawa: jeśli potrzebujemy dokładnych danych typu liczba rekordów, rozbudowanych raportów etc. to nigdy nie odpytujemy bazy z poziomu aplikacji PHP, tylko używamy specjalnego narzędzia do kolejkowania zadań (np. Rabita), silnika do danych (np. Lucyny) i aplikacji/skryptów ładujących dane z bazy. Liczbę zapytań wtedy ustawiamy stosownie do naszych możliwości i jest to kompletnie niezależne od aplikacji PHP i liczby użytkowników na stronie, w aplikacji produkcyjnej odświeżenie strony nie powinno generować zapytań do baz danych.
trueblue
Cytat(Pilsener @ 3.02.2018, 18:08:02 ) *
Podłącze się, bo może komuś się przyda:
  1. FROM tab_lacz1 t1, tytul t
- coś takiego nie powinno być w ogóle dopuszczalne w mysql, to tworzy iloczyn tabel, czyli jak masz w jednej 100 rekordów a w drugiej 1000 to w wyniku będzie 100 000 rekordów.

W teorii. W praktyce CROSS JOIN + WHERE zostanie zoptymalizowany i wykonany jak INNER JOIN.
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-2024 Invision Power Services, Inc.