• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Optymalizacja zapytania sql (Laravel Eloquent)

Object Storage Arubacloud
0 głosów
356 wizyt
pytanie zadane 22 lutego 2021 w SQL, bazy danych przez Bakkit Dyskutant (7,600 p.)
zamknięte 17 marca 2021 przez Bakkit

Cześć, mam mały problem z zapytaniami do bazy danych. Mam nadzieję, że pomożecie mi je zoptymalizować.

Problem polega na tym, że mając w bazie tylko 4 rekordy zużywam aż 18MB RAM na stronie głównej. W przyszłości może dojść do 30-40 wczytywanych rekordów per strona.

Tak wygląda struktura głównej tabeli:

Struktura tabeli relacyjnej (relacja one-to-one):

 

A o to akcja kontrolera strony głównej:

private $COLUMNS = ['id', 'name', 'motd', 'online_status', 'players_online', 'slots', 'version', 'icon'];

    public function __invoke(): View
    {
        $serversPremium = Server::with('data:votes,id')
            ->whereHas('data', function(Builder $query) {
                $query->where('premium', 1)->orderBy('votes', 'desc');
            })
        ->get($this->COLUMNS);

        $servers = Server::with('data:votes,id')
            ->whereHas('data', function(Builder $query) {
                $query->where('premium', 0)->orderBy('votes', 'desc');
            })
        ->paginate(20, $this->COLUMNS);

        return view('index.sections.server.index', [
            'serversPremium' => $serversPremium,
            'servers' => $servers
        ]);
    }

Wszystkie kolumny jakie wyciągam z tabel są wykorzystywane.

 

Rekordy premium i te "nie" premium są wrzucane do osobnych zmiennych, bo w widoku są wyświetlane w osobnych miejscach.

Troszkę w tych zapytaniach jest redundancji, wrzucę tam potem jakiegoś local scope'a, natomiast teraz dla przejrzystości jest to zrobione tak.

komentarz zamknięcia: Rozwiązanie problemu.

3 odpowiedzi

+1 głos
odpowiedź 27 lutego 2021 przez mordimer Mądrala (5,720 p.)
wybrane 17 marca 2021 przez Bakkit
 
Najlepsza
Po co ta relacja 1:1 w tym przypadku ? Pokaż w debugerze laravela co rzeczywiście zjada ta pamiec . Czemu to tak dziwnie wolasz invoke ? Nie podales koniguracji modelu i jak to wolasz po kolei. A jak to jest problem z eloquentem i sobie cos tam za duzo pobiera to pobierz sobie to czystym sqlem.
komentarz 27 lutego 2021 przez Bakkit Dyskutant (7,600 p.)

Po co ta relacja 1:1 w tym przypadku ?

W jednej tabeli są trzymane serwer i ich główne dane a w drugiej ich dane dodatkowe, każdy serwer ma dane główne i dodatkowe czyli każdy z tych rekordów w tabeli głównej ma swój rekord w tabeli relacyjnej. (Jeśli w tabeli głownej zostanie dodany serwer to w tabeli relacyjnej automatycznie zostanie dodany jego rekord z informacjami dodatkowymi).

 

Pokaż w debugerze laravela co rzeczywiście zjada ta pamiec

Co konkretnie pokazać?

 

Czemu to tak dziwnie wolasz invoke ?

Ponieważ to jest Single Action Controller, który zawsze posiada jedną akcje o nazwie __invoke.

 

Nie podales koniguracji modelu i jak to wolasz po kolei.

Nie bardzo rozumiem.

 

A jak to jest problem z eloquentem i sobie cos tam za duzo pobiera to pobierz sobie to czystym sqlem.

Tak wyglądają czyste zapytania, które generuje Eloquent (4):

select `id`, `name`, `motd`, `online_status`, `players_online`, `slots`, `version`, `icon` from `servers` where exists (select * from `servers_data` where `servers`.`id` = `servers_data`.`id` and `premium` = 1)
select `votes`, `id` from `servers_data` where `servers_data`.`id` in (1)
select `id`, `name`, `motd`, `online_status`, `players_online`, `slots`, `version`, `icon` from `servers` where exists (select * from `servers_data` where `servers`.`id` = `servers_data`.`id` and `premium` = 0)
select `votes`, `id` from `servers_data` where `servers_data`.`id` in (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29)

 

Oraz jeszcze ilość zaciąganych modeli:

Data: 29 - Model z bazy relacyjnej

Server: 29 - Model z bazy głównej

komentarz 28 lutego 2021 przez mordimer Mądrala (5,720 p.)

select `id`, `name`, `motd`, `online_status`, `players_online`, `slots`, `version`, `icon` from `servers` where exists (select * from `servers_data` where `servers`.`id` = `servers_data`.`id` and `premium` = 0)
select `votes`, `id` from `servers_data` where `servers_data`.`id` in (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29)

W tych dwóch zapytaniach masz odpowiedź na swoje pytanie. Nie wiem ile masz tam rekordów ale wygląda na to eloquent pod spodem pobiera wszystko i z tego dopiero skleja te dane. Spróbuj zrobić joina do tej drugiej tabeli i wyciągnij również te pola, które potrzebujesz z tej drugiej tabeli cos w tym stylu (w eloquencie sobie juz to napiszesz):

SELECT server.id, server.name i tak dalej ...., servers_data.votes
FROM server
INNER JOIN servers_data ON server.id=servers_data.server_id 
where server_data.premium = 1

A dlatego chciałem konfigurację modelu bo jakoś tą relację "data" zrobiłeś i z ciekawości chciałem ją zobaczyć. Chyba że laravel stał się jeszcze bardziej magiczny i nie trzeba tego teraz robić :D

 

 

 

 

  

0 głosów
odpowiedź 24 lutego 2021 przez Bakkit Dyskutant (7,600 p.)
@ref
0 głosów
odpowiedź 26 lutego 2021 przez Bakkit Dyskutant (7,600 p.)

Kurde chyba nikt nie wiesad

Podobne pytania

0 głosów
1 odpowiedź 162 wizyt
pytanie zadane 8 marca 2021 w PHP przez niezalogowany
0 głosów
0 odpowiedzi 176 wizyt
0 głosów
1 odpowiedź 301 wizyt

92,568 zapytań

141,420 odpowiedzi

319,618 komentarzy

61,954 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...