[SQL] Jak zmniejszyć liczbę zapytań ? :/ (optymalizacja)

0

Zrobiłem sobie mini-forum oparte na MySQL. Na nim przy każdym użytkowniku pokazywana jest data i godzina ostatniej wizyty danego użytkownika. Gdy na stronie zawsze jest 100 ostatnich wiadomości to, gdy się ona wczytuje to wykonuje się ponad 100 zapytań do bazy i ciągle baza mi pada (jak więcej osób na nim siedzi), bo za każdym razem jak strona jest odświeżana to przy każdym użytkowniku musi zostać pobrany czas ostatniej wizyty.
Listę użytkowników mam w osobnej tabeli i każdy rekord ma swój login, hasło i datę wizyty, a napisane posty mam w drugiej tabeli która zawiera treść postu, datę napisania, nazwę usera.

Jak można to zoptymalizować, bo brakuje mi już pomysłów :/ ?

PS. Jeśli czegoś nie rozumiecie z tego, co napisałem to piszcie - postaram się wyjaśnić...

0

OMG 100 zapytań? Powinieneś poważnie przemyśleć budowę całego forum :) Na 4programmers do wyświetlenia forum potrzeba w porywach do 11-12 zapytań (co i tak jest znaczną ilością). Może nie używasz JEFT JOIN i zapytań wiązanych (raczej to się tak nie nazywa, ale na tym polega)?

0

zastanow sie, czy nie pobierasz kilka razy tych samych danych. ciezko powiedziec, co robisz zle. podaj jakie masz tabele i co z nihc pobierasz. 100 zapytan, hhmm, a moze robisz cos w petli?

0

Wyświelam wszystkie 100 postów (ostatnich) z bazy i przy każdym poście pobieram (zapytaniem) czas ostatniej wizyty usera który napisał post, czyli w sumie daje to 100 zapytań pobierających czas wizyt.

0

Raczej potrzebujesz tylko 1 zapytania :)

Nie znam struktur Twoich tabel więc napiszę bardzo pobieżnie

select post_text, user_lastvisit <font color="green">//pobierze 2 pola: treść postu i datę wizyty usera</span>
from tabela_z_postami <font color="green">//tabela, skąd pobierzemy treść postu</span>
join tabela_z_userami on post_id_usera_autora = user_id <font color="green">//stąd weźmiemy info o userze</span>
order by post_id desc <font color="green">//sortujemy od najnowszych postów</span>
limit 0, 100; <font color="green">//i bierzemy tylko 100 najnowszych</span>

0

Dzięki Marooned !!
Zobaczę później co z tego wykombinuję, ale już wiem o co w tym chodzi :)

//EDIT:
i jeszcze małe pytanie:
bo mam w tabeli z userami nazwę id i w tabeli z postami nazwę id
jak to zrobić, że ON id=id (tylko, że to pierwsze id odwołuje się do tabeli users a to drugie do posts)
i czy mogę to zrobić np. tak, że ON nick1=nick2 (nick1 z tabeli users, nick2 z tabeli posts) czy też koniecznie musi być id jako liczby ?

0
fleming86 napisał(a)

i jeszcze małe pytanie:
bo mam w tabeli z userami nazwę id i w tabeli z postami nazwę id
jak to zrobić, że ON id=id (tylko, że to pierwsze id odwołuje się do tabeli users a to drugie do posts)
i czy mogę to zrobić np. tak, że ON nick1=nick2 (nick1 z tabeli users, nick2 z tabeli posts) czy też koniecznie musi być id jako liczby ?

SELECT * FROM posty
INNER JOIN users
ON posty.user_id = users.id

jak chcesz określone pola z tabeli to piszesz np. users.name

Poczytaj też o LEFT/RIGHT JOIN w zapytaniach sql

0

Jeśli oba pola mają taką samą nazwę (tu: id) to lepiej pisać:

SELECT pole1, pole2 FROM posty
JOIN users
USING (id)

Poza tym to wątek o optymalizacji, więc wszelkie "select *" są nie na miejscu.

0

bardzo fajny topik, więc lecimy dalej :) co jest lepiej użyć zamiast

SELECT

?
fleming86 z tymi 100 zapytaniami to przesadziłeś :d </b>

0

jak zrobiłem INNER JOIN to działa, a jak dałem samo JOIN to wywala mi błąd:

#1064 - Something is wrong in your syntax obok 'ON posty.user_id=users.id LIMIT 0, 30' w linii 1

błąd ten jest przy zapytaniu:

SELECT posty.text,users.wizyta FROM posty JOIN users ON posty.user_id=users.id

albo coś robiłem źle, albo marooned zapomniał o INNER ?! nie wiem, ważne że działa mi jak zrobię to tak:

SELECT posty.text,users.wizyta FROM posty INNER JOIN users ON posty.user_id=users.id

0
fleming86 napisał(a)

albo coś robiłem źle, albo marooned zapomniał o INNER ?!
Rzeczywiście - pomyliło mi się, że INNER jest domyślne a nie OUTER.

Bełdzio - o co pytasz? bo nie zrozumiałem.

0
Marooned napisał(a)

Bełdzio - o co pytasz? bo nie zrozumiałem.

Marooned napisał(a)

Poza tym to wątek o optymalizacji, więc wszelkie "select *" są nie na miejscu.

jeśli nie select to co ??

// ps jak ktoś zna jeszcze jakieś triki ;) to piście :)

0

Jemu chodziło o "SELECT *" (gwiazdka!). Gwiazdka jest m.in. dlatego do kitu, bo wybiera wszystkie kolumny, nawet, te co sa niepotrzebne.

0
Krolik napisał(a)

Jemu chodziło o "SELECT *" (gwiazdka!)
W rzeczy samej.
Read: http://4programmers.net/Forum/211939#211939

0

A ja mam kolejną prośbę o napisanie, czy da sie to jakoś zoptymalizować?

Jest to skrypt dodawania do tabeli IP i czasu odwiedzin (IP nie może sie powtarzać)

$msql = @mysql_connect($db_host,$db_user,$db_pass) or die("Unable to connect to mySQL server");
mysql_select_db($db_name);

$sql=  "SELECT COUNT(ip) AS numrows FROM tab_ip WHERE ip='".mysql_escape_string($_SERVER['REMOTE_ADDR'])."'";
$result = mysql_query($sql) or die(mysql_error());
if($row=mysql_fetch_array($result)) $poz=$row["numrows"];else $poz=0;

if ($poz==0) {
 $sql = "INSERT INTO tab_ip VALUES ('','".mysql_escape_string(time())."','".mysql_escape_string($_SERVER['REMOTE_ADDR'])."')";
 $query = mysql_query($sql) or die(mysql_error());
}
mysql_close($msql);

PS. Czemu skrytpy php tutaj na forum sie nie kolorują ?

//EDIT:
i jeszcze jedno:

To statystyka mojej bazy:

Uptime: 6436279
Threads: 15
Questions: 1759213604
Slow queries: 4955
Opens: 128714876
Flush tables: 1
Open tables: 512
Queries per second avg: 273.328

To dobrze czy źle? bo trochę mi się nie podoba te 273 zapytań/sek. i cały czas wzrasta :/

//EDIT #2

i kolejne pytanie:
Jak uaktualnić jakieś dane w bazie (np. jakąś liczbę), i jeśli rekord nie istnieje to go utworzyć - oczywiście w jednym zapytaniu ?
Bo ja robię tak, że najpierw sprawdzam czy istnieje rekord - jeśli tak to UPDATE, jeśli nie to INSERT

1 użytkowników online, w tym zalogowanych: 0, gości: 1