[MYSQL] Problem wydajności bazy danych.

0

Witam, mam taki problem u mnie na portalu. Mianowicie, wczoraj wywaliło nam bazę bo jak to stwierdziła firma googlebot tak szalał, że obciażył koszmarnie baze.
Admini po sprawdzeniu podali że jest jedno zapytanie z dwoma JOIN-ami które trwa 11 sekund.
Googlebot wchodzil na linki co 3,4 sekundy, można by się z tego cieszyć ale .... no własnie portal umarł.

Zapytanie operuje na 3 tabelach , jedna tabela ok 300tys rekordów , 4 pola zawierają dużo tekstu, druga tabela to tabela województw i tabela miast. Zapytanie złożony jest z dwóch JOIN-ów i trwa 11 sekund.
Zaznaczam ze tabele nie posiadaja zadnych kluczy typu INDEX tylko PRIMARY.

Czy w takiej sytuacji googlebot mógł rozwalić stronę? I czy zapytanie które się wykonuje 11 sekund nie powinno zostać zoptymalizowane poprzez założenie indeksów ?

0
  1. moze warto ograniczyc czestos odwiedzin google bota (i innych byc moze tez)
  2. z pewnoscia jesli ta query sie czesto wykonuje to 11s to jakis koszmarny czas, zalozenie odpowiednich indexow powinno pomoc (ale nie koniecznie rozwiazac problem)
  3. sprobuj zooptymalizowac query, 300k to nie tak duzo nawet dla MySql, zakladam ze nie trzeba wybierac wszystkich 300k rekordow, wiec pewnie zle jest query napisana, sprobuj na poczatek maksymalnie zawezic poszczegolne dane, a nastepnie laczyc

jesli mozesz podaj nam query i struktury tabel moze cos doradzimy

0

Podaj przyklad danych (nie musza byc oczywiscie realne) i zapytania oraz glownie kolumn na jakich operuje, to bedzie latwiej cos poradzic.

0

Tabela 1:

CREATE TABLE IF NOT EXISTS `tabela1` (
  `idbiuletyn` bigint(20) unsigned NOT NULL auto_increment,
  `data_dodania` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `pozycja` bigint(20) unsigned NOT NULL,
  `data_publikacji` date NOT NULL,
  `nazwa` tinytext NOT NULL,
  `ulica` tinytext NOT NULL,
  `nr_domu` varchar(20) NOT NULL,
  `nr_miesz` varchar(20) NOT NULL,
  `miejscowosc` int(10) unsigned NOT NULL default '0',
  `kod_poczt` char(6) NOT NULL,
  `wojewodztwo` int(10) unsigned NOT NULL default '0',
  `tel` varchar(60) NOT NULL,
  `fax` varchar(60) NOT NULL,
  `internet` tinytext NOT NULL,
  `regon` varchar(20) NOT NULL,
  `e_mail` tinytext NOT NULL,
  `ogloszenie` char(6) NOT NULL,
  `rodzaj_zam` text NOT NULL,
  `nazwa_zamowienia` text NOT NULL,
  `rodz_zam` char(1) NOT NULL,
  `przedmiot_zam` text NOT NULL,
  `kod_trybu` char(2) NOT NULL,
  `data_skl` char(10) NOT NULL,
  PRIMARY KEY  (`idbiuletyn`),
  UNIQUE KEY `pozycja` (`pozycja`,`data_publikacji`),
  KEY `miejscowosc` (`miejscowosc`),
  KEY `wojewodztwo` (`wojewodztwo`),
  KEY `data_dodania` (`data_dodania`),
  KEY `kod_trybu` (`kod_trybu`),
  FULLTEXT KEY `nazwa` (`nazwa`,`rodzaj_zam`,`nazwa_zamowienia`,`przedmiot_zam`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=571401 ;

Tabela 2:

CREATE TABLE IF NOT EXISTS `wojewodztwa` (
  `idw` int(11) NOT NULL auto_increment,
  `nazwa` varchar(20) character set utf8 collate utf8_unicode_ci default NULL,
  PRIMARY KEY  (`idw`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=42 ;

Tabela 3:

CREATE TABLE IF NOT EXISTS `biuletyn_kategorie` (
  `idbiuletyn` bigint(20) NOT NULL,
  `idm` int(11) NOT NULL,
  PRIMARY KEY  (`idbiuletyn`,`idm`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

I zapytanie wygląda tak:

SELECT data_publikacji, pozycja, nazwa_zamowienia, idbiuletyn, w.nazwa AS wojewodztwo, m.nazwa AS miejscowosc FROM tabela1 b JOIN biuletyn_kategorie USING
(idbiuletyn) JOIN wojewodztwa w ON b.wojewodztwo = w.idw JOIN miasto m ON b.miejscowosc = m.idm WHERE  idbiuletyn > "40767" ORDER BY data_publikacji, pozycja LIMIT 1;

Tabela 1 posiada 554tys rekordow, wojewodztwa: 41, biuletyn_kategorie: 342tys

Zapytanie trwa 11 sekund.

0

Zaloz indeksy na elementach w where (bo KEY to chyba tylko klucz obcy, bez indeksu) + strzelam, ze sortowanie po dacie publikacji 0,5mln wierszy to nie jest szybka operacja. Sprobuj bez niej, a pozniej z indeksem na niej. Do tabeli biuletyn_kategorie dolaczyl bym wewnetrzny klucz glowny na int, a oba pola zaindeksowal osobno.

0

Zasugerowałem dodanie indeksów i usłyszałem odpowiedź że indeksy już są założone hmmm czy ja czegoś nie widzę w strukturze czy ktoś mi próbuje coś wmówić ? :)

0

Sprawdzilem sobie, KEY oznacza tez indeks. Zatem sa indeksy, ale nie ma na dacie publikacji, po ktorej chcesz sortowac calkiem spora ilosc wierszy. Probowales wywolac z EXPLAIN?

0

A co myślicie gdyby założyć widoki ? TAbele źródłowe zmieniają się tylko raz w cronie, później następuje tylko odczyt, czy nie lepiej zrobić parę widoków i później już nie JOIN-ować tylko odpalać proste selecty ?

0

WHERE idbiuletyn > "40767"
takie pobczne pyt. jesli idbiuletyn to bigint czemu podajesz jako string wartsoc w warunku?
to where dalbym przed joinem, aby maksymalnie przefiltorwac tabele1 przed zlaczeniem
nie jestem pewien czy widok cos pomoze, jesli bedzie on zlaczeniem tych 3 tabel, bez filtorwania
najlepiej zrob kopie tej bazy i zacznij eksperymentowac, usun wszystkie dodatkowe indexy i zaloz on nowa jak powiedzial johny_bravo, staraj sie maksymalnie zawezic zbiory przed ich zlaczeniem
i jak zauwazyl johny_bravo operacja sortowania moze byc bardzo kosztowna, co dzieje sie pozniej z wybranymi danymi? zasilaja jakis raport czy pokazuja sie klientowi? mozne przeniesc sortowanie na poziom klienta, aby odciazyc serwer bazy danych
jesli sa to dane specjalnie pod boty przygotowywane, moze co jakis czas (raz na dzien, co kilka h, nie wiem jak czesto zmieniaja sie dane), generowac statyczna strone (czysty html), ktory boty sobie beda indexowac

0

przede wszystkim explain rzeczywistego zapytania bo gdybać to sobie można

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