Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Strona główna własnego forum
Forum PHP.pl > Forum > Gotowe rozwiązania
Denver
Witam. Napisałem swoje forum (nie korzystam więc z phpBB). Mam problem z zapytaniem generującym strukturę forum, tj. kategorie, w nich fora, a dla każdego forum jest dopisana ostatnia wiadomość (i do niej link).

Struktura tabel mniej więcej taka jak w phpBB. System szablonów napisałem sam, więc niech nie dziwią was polecenia $tlp -> add...

Oto część kodu php z pliku index.php


[php:1:93305db715]<?php
$sql = "SELECT
c.id AS c_id, c.name AS c_name,
f.id AS f_id, f.name AS f_name, f.description AS f_description
FROM ".$tables['forums']." f, ".$tables['categories']." c
WHERE f.category_id=c.id
ORDER BY c.sequence ASC, f.sequence ASC";

$for_result = mysql_query ($sql);
if ($for_result) {

$last_category = 0;
while ($for_row = mysql_fetch_assoc ($for_result)) {

$cat_id = $for_row ['c_id'];

if ($last_category != $cat_id) {

$last_category = $cat_id;
$cat_name = $for_row ['c_name'];

$tpl -> add ("CATEGORY_ID", $cat_id);
$tpl -> add ("CATEGORY_NAME", $cat_name);
print $tpl -> get ("forum_category");

}

$last_post = $lang ['No_Posts'];
$topics_counter = $posts_counter = 0;
$forum_id = $for_row ['f_id'];

$sql = "SELECT p.id FROM ".$tables['posts']." p, ".$tables['topics']." t
WHERE p.topic_id=t.id AND t.forum_id=$forum_id";
$posts_counter = mysql_num_rows ( mysql_query ($sql) );


$sql = "SELECT p.id, p.author_id, p.date FROM ".$tables['posts']." p, ".$tables['topics']." t
WHERE t.forum_id=$forum_id AND p.topic_id=t.id ORDER BY p.id DESC LIMIT 1";
$result = mysql_query ($sql);

while ($post_row = mysql_fetch_assoc ($result)) {

$sql = "SELECT id FROM ".$tables['topics']." WHERE forum_id=$forum_id";
$topics_counter = mysql_num_rows ( mysql_query ($sql) );

$last_post_id = $post_row ['id'];
$post_date = $post_row ['date'];

if ($post_date) {

$tpl -> add ("LAST_POST_DATE", strftime ("%d.%m.%Y %H:%M", $post_date));
$tpl -> add ("AUTHOR_ID", $post_row ['author_id']);
$tpl -> add ("AUTHOR_NAME", getNameByID ($post_row ['author_id']));

$tpl -> add ("TOPIC_ID", $topic_id);
$tpl -> add ("LAST_POST_ID", $last_post_id);
$last_post = $tpl -> get ("forum_last_post");

$time = getElement ("last_visit", $tables['users'], "name='".$_COOKIE ['logged_username']."'");
$time -= LAST_POST_OFFSET;

if ($post_date >= $time) {
$tpl -> add ("FORUM_FOLDER", "_new");
} else {
$tpl -> add ("FORUM_FOLDER", "");
}

}

}


if ($topics_counter == 0 || $_COOKIE ['logged'] != 1) {
$tpl -> add ("FORUM_FOLDER", "");
}
$tpl -> add ("FORUM_ID", $for_row ['f_id']);
$tpl -> add ("FORUM_NAME", $for_row ['f_name']);
$tpl -> add ("FORUM_DESCRIPTION", $for_row ['f_description']);
$tpl -> add ("TOPICS", $topics_counter);
$tpl -> add ("POSTS", $posts_counter);
$tpl -> add ("LAST_POST", $last_post);



print $tpl -> get ("forum_forum");

}


$total_topics = mysql_num_rows ( mysql_query ("SELECT id FROM ".$tables['topics']) );
$tpl -> add ("STATS_TOTAL_TOPICS", $total_topics);

$total_posts = mysql_num_rows ( mysql_query ("SELECT id FROM ".$tables['posts']) );
$tpl -> add ("STATS_TOTAL_POSTS", $total_posts);

$total_users = mysql_num_rows ( mysql_query ("SELECT id FROM ".$tables['users']) );
$tpl -> add ("STATS_TOTAL_USERS", $total_users);

$last_user_id = getLastElement ($tables['users'], "id > 0");
$tpl -> add ("STATS_LAST_USER_ID", $last_user_id);

$last_user_name = getElement ("name", $tables['users'], "id = $last_user_id");
$tpl -> add ("STATS_LAST_USER_NAME", $last_user_name);


$sql = "SELECT user_id FROM ".$tables ['users_online']." WHERE time >=".(time () - USERS_ONLINE_OFFSET)." ORDER BY user_id ASC";
$result = mysql_query ($sql);
$results = mysql_num_rows ($result);

$count = 0;
while ($row = mysql_fetch_assoc ($result)) {
$count++;

$username = getNameByID ($row ['user_id']);
$users_online .= "<a href='profile.php?mode=view&user_id=".$row ['user_id']."'>$username</a>";
if ($count < $results) $users_online .= ", ";
}
$tpl -> add ("STATS_USERS_ONLINE_COUNT", $count);
$tpl -> add ("STATS_USERS_ONLINE", $users_online);

$users_record = getElement ("users_record", $tables ['config'], "1=1");
$tpl -> add ("STATS_USERS_RECORD", $users_record);

$users_record_date = getElement ("users_record_date", $tables ['config'], "1=1");
$tpl -> add ("STATS_USERS_RECORD_DATE", strftime ("%d.%m.%Y %H:%M", $users_record_date));

print $tpl -> get ("forum_list_end");
} else {
information ($lang ['Information'], $lang ['Cant_Read_Category'], 0);
}
?>[/php:1:93305db715]


Problem jest w tym, że zapytanie wykonuje się dosyć długo (ok. 2 sekund) na forum, gdzie postów jest ok. 2000.

Moje pytanie: Co należało by w tym skrypcie zoptymalizować?

Podpatrzyłem skrypt forum phpBB i zauważyłem tam w pewnym momencie polecenie "LEFT JOIN ....". Szukałem w manualu MySQL objaśnienia, ale coś nie bardzo to jest opisane sad.gif

Proszę o pomoc.


PS. Forum znajduje się na TEJ STRONIE

----------------
php Poczatkujacy >> Skrypty
Seth
adwol
Cytat
Problem jest w tym, że zapytanie wykonuje się dosyć długo (ok. 2 sekund) na forum, gdzie postów jest ok. 2000.

Moje pytanie: Co należało by w tym skrypcie zoptymalizować?

To pierwsze? Widzę, że sortujesz po polu sequence, spróbuj więc założyć indeks na tym polu.
Cytat
Podpatrzyłem skrypt forum phpBB i zauważyłem tam w pewnym momencie polecenie "LEFT JOIN ....". Szukałem w manualu MySQL objaśnienia, ale coś nie bardzo to jest opisane sad.gif

A to czytałeś: http://www.mysql.com/documentation/mysql/b...rence.html#JOIN?
Denver
Cytat
Cytat
Problem jest w tym, że zapytanie wykonuje się dosyć długo (ok. 2 sekund) na forum, gdzie postów jest ok. 2000.

Moje pytanie: Co należało by w tym skrypcie zoptymalizować?

To pierwsze? Widzę, że sortujesz po polu sequence, spróbuj więc założyć indeks na tym polu.
Cytat
Podpatrzyłem skrypt forum phpBB i zauważyłem tam w pewnym momencie polecenie "LEFT JOIN ....". Szukałem w manualu MySQL objaśnienia, ale coś nie bardzo to jest opisane sad.gif

A to czytałeś: http://www.mysql.com/documentation/mysql/b...rence.html#JOIN?


czytałem, ale nadal tego nie rozumiem... nie podchodzi mi ten manual sad.gif
poza tym pole sequence jest wazne, jesli np. kategoria jest 2 nal liscie na stronie glownej, to ma sequence 20, jesli pierwsza - 10, jesli 8 - 80 itd...

prosze o pomoc sad.gif
adwol
Cytat
czytałem, ale nadal tego nie rozumiem... nie podchodzi mi ten manual sad.gif

Ale czego nie rozumiesz? LEFT JOINa? Najlepiej wytłumaczę Ci to na przykładzie.
Masz dwie tabele A i B o takiej zawartości:
Tabela A:
Kod
+------+------+

| a1   | a2   |

+------+------+

|    1 |    2 |

|    3 |    4 |

|    5 |    6 |

+------+------+

Tabela B:
Kod
+------+------+

| b1   | b2   |

+------+------+

|    2 |   20 |

|    6 |   60 |

+------+------+

Teraz jeśli wykonamy zapytanie z wewnętrznym złączeniem tych dwóch tabel:
[sql:1:7156597aa8]select * from A,B where a2=b1[/sql:1:7156597aa8]
to dostaniemy:
Kod
+------+------+------+------+

| a1   | a2   | b1   | b2   |

+------+------+------+------+

|    1 |    2 |    2 |   20 |

|    5 |    6 |    6 |   60 |

+------+------+------+------+

a jeśli wykonamy zapytanie ze złączeniem lewym zewnętrznym (czyli właśnie LEFT JOIN):
[sql:1:7156597aa8]select * from A LEFT JOIN B on a2=b1[/sql:1:7156597aa8] to dostaniemy:
Kod
+------+------+------+------+

| a1   | a2   | b1   | b2   |

+------+------+------+------+

|    1 |    2 |    2 |   20 |

|    3 |    4 | NULL | NULL |

|    5 |    6 |    6 |   60 |

+------+------+------+------+

Widać różnicę? W przypadku złączeń zewnętrznych wszystkie wiersze (ewentualnie ograniczone przez wyrażenie po WHERE) jednej z tabel wchodzą do wyniku (w tym przypadku lewej tabeli, stąd LEFT JOIN). Nieznane wartości kolumn drugiej tabeli są wypełniane wtedy NULLami.
Cytat
poza tym pole sequence jest wazne, jesli np. kategoria jest 2 nal liscie na stronie glownej, to ma sequence 20, jesli pierwsza - 10, jesli 8 - 80 itd...

Ok, ale załóż na niej indeks. To powinno przyspieszyć wyszukiwanie i sortowanie po niej:
[sql:1:7156597aa8]CREATE INDEX tabela_idx ON tabela (sequence)
[/sql:1:7156597aa8]
Denver
Ok, założyłem index, ale wcale to za mocno wyszukiwania nie przyspieszyło... Mam do Was prośbę - pomozcie mi w zoptymalizowaniu tego kodu. Bardzo mi zalezy na tym, aby wykonywal sie on szybciej, ale nie potrafie tego zrobic :?

Z góry dzieki za kazdą pomoc

Pozdrawiam
Denver
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.