Zobacz pełną wersję : Problem z wydajnością
Mam problem z wydajnością po przełączeniu tabel z myisam na innodb, w zasadzie problem dotyczy tylko tabeli #__categories (ok 4 tys rekordów), gdy ta tabela zostanie przełączona na innodb strona ładuje się po kilkanaście sekund.
Serwer: debian 9, nginx, mariadb (na starym serwerze apche i mysql 5.5 było to samo). Nie ma różnicy czy rozszezenia są włączone czy nie.
4 tys. rekordów? masz tyle kategorii? To artykułów masz chyba kilkadziesiąt tysięcy ;) Na to potrzebujesz bazy klasy enterprise. InnoDB oferuje bardziej złożoną strukturę kluczy niż MyIsam (FOREIGN KEYS) i odżwieżanie kluczy jest niestety wolniejsze w InnoDB.
Artykułów mam sporo mniej :) bo w kategoriach prezentowane sa produkty ze sklepu internetowego ktore sa wczytywane z innej bazy (wiem, troche pokrecone), o FOREIGN KEYS wiem, natomiast nie sadzilem ze przez to jest taka roznica wydajnosci, myslalem ze mozna to jakos rozwiazac ;(
Którą wersję MariaDB masz?
Z częścią rzeczy MariaDB radzi sobie lepiej niż MySQL, warto by zajrzeć do jej konfiguracji.
Pomyśl nad przejściem na PostgreSQL, jeśli masz ją zindeksowaną, to hula jak marzenie.
Z częścią rzeczy MariaDB radzi sobie lepiej niż MySQL, warto by zajrzeć do jej konfiguracji.
dlatego zostala wybrana MariaDB :)
konfiguracja wydaje sie ze jest zrobiona dobrze (nie robilem jej sam, a firma ktora zajmuje sie konfiguracja serwerow itd), wszystkie pozostale witryny po zmianach zaczely funkcjonowac o wiele wydajniej, problem dotyczy tylko tej jednej witryny i tej jedynej tabeli.
Co do wersji MariaDB:
MariaDB: 10.2.10-MariaDB-10.2.10+maria~stretch - mariadb.org
nginx: nginx/1.10.3
PHP: 7.0.19
mjmartino
02-12-2017, 19:49
Podepnij sobie dysk SSD drugi do instancji i tam przenieść bazę.
Lub zepnij w raid 0 a kopie wysyłaj gdzie indziej lub na storage obiektowy jak ta serwerowania posiada.
Ewentualnie można ograniczyć na stronach z problem ładowania kategorii które pewnie lądują się wszystkie, ograniczyć tylko do niezbędnych.
tez nie :) mam dyski w rajdzie intela nvme
A jak są pobierane dane z zewnętrznej bazy danych dla tej strony?
mjmartino
03-12-2017, 00:17
Pytanie a jak doszedłeś że to ta tabela ? i akurat baza nie wyrabia
A jak są pobierane dane z zewnętrznej bazy danych dla tej strony?
uzytkownik bazy joomla ma uprawnienia dostepu do drugiej bazy, bo sa na tym samym serwerze i wykonywane jest zapytanie bezposrednio do "zewnetrznej" bazy - sprawdzalem z wlaczonym pobieraniem danych z zewnetrznej bazy i wylaczonym - roznicy nie ma
To jeszcze napisz odpowiedź na pytanie @mjmartino.
Pytanie a jak doszedłeś że to ta tabela ? i akurat baza nie wyrabia
Ponieważ po przełączeniu tabel na InnoDB odrazu widać było, że czas generowania strony wynosi dobre kilkanascie sekund, wiec zajrzalem do logow serwera i mysql zalogowal przykladowo nastepujace zapytanie jako long_query_time:
SELECT c.id, c.asset_id, c.access, c.alias, c.checked_out, c.checked_out_time, c.created_time, c.created_user_id, c.description, c.extension, c.hits, c.language, c.level,
c.lft, c.metadata, c.metadesc, c.metakey, c.modified_time, c.note, c.params, c.parent_id,
c.path, c.published, c.rgt, c.title, c.modified_user_id, c.version, CASE WHEN CHAR_LENGTH(c.alias) != 0 THEN CONCAT_WS(':', c.id, c.alias) ELSE c.id END as slug
FROM zfgey_categories as c
LEFT JOIN (SELECT cat.id as id FROM zfgey_categories AS cat JOIN zfgey_categories AS parent ON cat.lft BETWEEN parent.lft AND parent.rgt WHERE parent.extension = 'com_content' AND parent.published != 1 GROUP BY cat.id) AS badcats ON badcats.id = c.id
LEFT JOIN zfgey_categories AS s ON (s.lft <= c.lft AND s.rgt >= c.rgt) OR (s.lft > c.lft AND s.rgt < c.rgt)
WHERE (c.extension='com_content' OR c.extension='system') AND c.access IN (1,1,5) AND c.published = 1 AND badcats.id is null AND s.id=8
GROUP BY c.id, c.asset_id, c.access, c.alias, c.checked_out, c.checked_out_time,
c.created_time, c.created_user_id, c.description, c.extension, c.hits, c.language, c.level,
c.lft, c.metadata, c.metadesc, c.metakey, c.modified_time, c.note, c.params, c.parent_id,
c.path, c.published, c.rgt, c.title, c.modified_user_id, c.version
ORDER BY c.lft;
wiec przelaczylem #__categories spowrotem na myisam i strona ponownie zaczela funkcjonowac jak nalezy
Zrób sobie tabelę, w której będziesz agregował dane z obu baz (przez jakieś api), pamiętaj o zoptymalizowaniu jej indeksów.
InnoDB z definicji potrzebuje więcej pamięci niż MyISAM, a żeby działało szybciej to trzeba przeprojektować, strukturę tabel i przepływ danych w niej zawartych. Zapytanie, które prezentujesz nie należy do najprostszych i czytelnych. Może warto do niego usiąść i je uprościć.
csthomas
09-12-2017, 22:35
Powyższe zapytanie SQL jest dość pamięciożerne.
Póki co możesz odnaleźć miejsce gdzie jest generowane to zapytanie i wyrzucić kolumny po GROUP BY c.id.
Dla J3.8.x plik libraries/src/Categories/Categories.php:
Linia 294:
// Group by
$query->group(
'c.id, c.asset_id, c.access, c.alias, c.checked_out, c.checked_out_time,
c.created_time, c.created_user_id, c.description, c.extension, c.hits, c.language, c.level,
c.lft, c.metadata, c.metadesc, c.metakey, c.modified_time, c.note, c.params, c.parent_id,
c.path, c.published, c.rgt, c.title, c.modified_user_id, c.version'
);
zmień na:
// Group by
$query->group(
'c.id'
);
Ten prosty zabieg powinien wystarczyć na początek.
vBulletin® v4.2.5, Prawa przedruku © 2024 vBulletin Solutions, Inc. Wszystkie prawa zastrzeżone.
Tłumaczenie: Polskie Centrum Joomla!