Który kod jest bardziej wydajny?

0

Witam, Który kod jest bardziej wydajny oraz jaka jest różnica między tymi dwoma az tak duza?

sposób 1 (mój)

$ChatMessages = $Connect_Server->prepare('SELECT * FROM chat DESC ASC LIMIT 100');
$ChatMessages->execute();

foreach($ChatMessages as $ChatMessage) {
$accounts = $Connect_Server->prepare('SELECT * FROM accounts WHERE id = :account_id LIMIT 1');
$accounts->bindValue(':account_id', $ChatMessage['account_id'], PDO::PARAM_INT);
$accounts->execute();

foreach($accounts as $account){

}
$accounts->closeCursor();
}
$ChatMessages->closeCursor();`

sposób 2 (kolegi)

	$QueryGetMessages = $Connect_Server->query('SELECT accounts.user_name, accounts.ranga, accounts.color_name, accounts.color_message, accounts.effect_name, accounts.effect_message, accounts.gender, accounts.avatar, chat.text, chat.create_date FROM accounts INNER JOIN chat ON accounts.id = chat.account_id ORDER BY create_date DESC');
    $Messages = $QueryGetMessages->fetchAll(PDO::FETCH_ASSOC);
	$Messages = array_reverse($Messages);
1

Sposób nr 2 jest wydajniejszy, czytelniejszy, prostszy w modyfikacji.
Nie do tylko końca rozumiem po co został zrobiony array_reverse przy "ORDER BY create_date DESC"

Ucz się od kolegi :)

3

"Select *" robi sie tylko w nieprodukcyjnym kodzie - szkolenia, do ksiazki, do zrobienia na wczoraj raportu.

Jak masz 200 pol w tabeli i pobierasz przynajmniej 1000 rekordow to powinienes poczuc roznice.

Jesli natomiast pol wybierasz tyle samo w obu przypadkach to i tak lepiej wg drugiego sposobu - ze wzgledu na zdrowie psychiczne przyszlych pokolen zmieniajacych ten kod.

0
Programistyczny napisał(a):

Witam, Który kod jest bardziej wydajny oraz jaka jest różnica między tymi dwoma az tak duza?

Masz oba kody, to na chłopski rozum powinieneś już widzieć co jest lepsze^^

Co do Twojego sposobu, to Twój kod na oczy nie widział takiego czegoś jak optymalizacja.

0

Zrobienie n+1 zapytań na pewno nie jest optymalnym rozwiązaniem.

2

Bardzo dużo zależy od samej bazy (indeksy).
Poza tym oba kody robią różne rzeczy. Drugi kod pobiera WSZYSTKIE dane z tabeli accounts (które są w chat), a pierwszy kod wybiera sobie JAKIS JEDEN rekord z tej tabeli (przy założeniu, że account-id nie jest unikalny, a nic o tym nie wiemy...)

1

W programowaniu najważniejsza jest wyobraźnia. Pewnie ktoś to przedemną powiedział, ale jeżeli nie, to możecie to umieścić w jakiejś złotej księdze cytatów ;)

0

2 sposób jest najbardziej wydajniejszy i mniej zapytań wykonuje. Im mniej zapytań tym lepiej.

1

Po pierwsze, jak już pisali koledzy wyżej, zawsze pobieraj tylko te dane, które potrzebujesz. A więc "SELECT *" odpada co by to nie było. Nie warto tak robić nawet dla testu, ucz się robić "dobrze". ;)

Po drugie jeżeli tworzysz bardziej skomplikowane zapytania zwykle bardziej opłaca się je wykonać jako jedno większe z join-ami. Jeżeli okazuje się, że zapytanie wykonuje się długo (setki milisekund lub więcej) to sprawdzasz czy masz odpowiednio dodane indeksy. Jeżeli nadal jest długo możesz próbować dzielić operację i wykonywać zapytania z limitem (ja jeszcze nie miałem takiej potrzeby) albo powinieneś próbować inaczej łączyć tabele. Używając odpowiednio indeksów możesz pobrać naprawdę kupę danych łącząc kilka/wiele tabel i wciąż trzymać się w dziesiątkach milisekund.

Pamiętaj też, że ze wzrostem ilości danych wykonywanie zapytań w foreach-ach będzie mocno spowalniać skrypt.

0

czyli zamiast kilku foreachow mam dać inner joni lub left join tak?
przykładowo:

	$players = $Connect_Player->prepare("SELECT player.id,player.level,player.name,account_id FROM player INNER JOIN account.account ON account.id = player.account_id INNER JOIN common.gmlist ON gmlist.mAccount != account.login WHERE status = 'OK' ORDER BY level DESC,exp DESC LIMIT 10");
	$players->execute();

	echo('<div class="BOX_RIGHT_HIGHSCORE_NAME">');
	foreach($players as $player){

    }

czy mam też uzyć fetchall i query?
czy to bez roznicy?

a i jeszcze jedno.
da sie np jakos te inner joiny lub left joiny pakowac w dodatkowy nawias czy cos? zeby wiedziec gdzie co jest?

1

Tak, w tym przypadku (i w większości innych) to zapytanie do bazy będzie dużo wydajniejsze.
W zależności od tego co potrzebujesz, masz kilka typów JOINów (najczęściej używa się LEFT/RIGHT/INNER, ale jest ich jeszcze kilka). INNER JOIN w mysql jest używany domyślnie po użyciu samego słowa "JOIN".
fetchall - https://www.php.net/manual/en/pdostatement.fetchall.php
query - https://www.php.net/manual/en/pdo.query.php
tak więc nie, nie musisz tego używać.
Jeżeli nie musisz bindować parametrów i masz pewność, że wszystkie dane są poprawnie oczyszczone, to możesz użyć query. Gdy parametry pochodzą od użytkownika, użyłbym prepare i execute, chyba że lubisz życie na krawędzi. Ogólnie dla bezpieczeństwa, używałbym zawsze prepare + execute.

Po co nawias? Możesz łatwo rodzielić kod SQL enterami np.

"
SELECT player.id,player.level,player.name,account_id 
FROM player
INNER JOIN account.account ON account.id = player.account_id 
INNER JOIN common.gmlist ON gmlist.mAccount = account.login 
WHERE status = 'OK' 
ORDER BY level DESC,exp DESC 
LIMIT 10
"

Zresztą nawiasy są przede wszystkim używane do SUBQUERY.

Edit:
Nie wiem czy to było zamierzone, ale zauważyłem dopiero teraz:

INNER JOIN common.gmlist ON gmlist.mAccount  != account.login 

Co miałeś na myśli wstawiając do zapytania != ?

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