Autor Zpráva
Scorpio1337
Profil
Ahoj.
Ve svém systému počítám s tím, že bude mít v budoucnu i několik miliónů záznamů v databázi.
Co byste poradili pro optimalizaci takového systému?

Třeba maximální počet řádků v tabulce, protože počítám s tím, že bude asi lepší rozdělit tabulky na menší kusy s omezeným počtem záznamů a vždy když bude překročen, tak založit novou.

Děkuji za vaše rady.
Petr__
Profil *
Třeba do nejběžnějších MyISAM tabulek se vejde několik miliard řádků a změnou konfigurace se dá dostat ještě na řádově vyšší hodnoty, takže obecně nějaké rozdělování tabulek kvůli pár milionu řádků není třeba řešit. Nicméně to, jak máte DB strukturovanou, její typ a relace mezi tabulkami, indexy, účel, atd. jste neuvedl. A bez toho se nedá nijak radit.
Scorpio1337
Profil
Databázi zatím navrhuji. Ale popíšu tu zhruba co je v plánu.
Počítám, že časem by se do systému mohlo registrovat zhruba 100 tisíc uživatelů a průměrně každý uživatel přidá asi 100 příspěvky. K těmto záznamům bude moc přidávat komentáře a taky by to mohlo být průměrně tak 100 k jednomu.
Takže při těchto číslech máme tabulku s Uživateli kde je 100 tisíc záznamů. Pak tabulku Příspěvky s 10 000 000 záznamy a pak komentáře s 1 miliardou záznamů.
Samozřejmě tyhle čísla jsou asi přehnané, ale po pár letech by se to mohlo k tomuhle přiblížit a rád bych měl systém na tohle připraven. Jde mi o to, abych pak když si chci vytáhnout třeba komentáře nějakého příspěvku nečekal půl minuty než to databáze zpracuje. Pokud možno to chci co nejvíce optimalizovat první softwarově a až pak se poohlížet o výkonějším serveru.
Davex
Profil
Scorpio1337:
Jde mi o to, abych pak když si chci vytáhnout třeba komentáře nějakého příspěvku nečekal půl minuty než to databáze zpracuje.
Bude-li index na sloupci, podle kterého se vyhledává, tak to bude vcukuletu.
Scorpio1337
Profil
Spíš tam bude u každého komentáře sloupec s ID příspěvku ke kterému patří, takže to bude nějak takhle:
select * from komentare where id_prispevku=40

A tím to vybere třeba 50 komentářů.
Scorpio1337
Profil
Tak jsem vytvořil zkušební tabulku, do které jsem měl v plánu dát 1 miliardu řádků.
Tabulka měla simulovat ty komentáře. Takže tam bylo primární ID, pak sloupec POD, který měl simulovat ID příspěvku a poté TEXT, kde jsem dal asi 200 znakové lorem ipsum.

Ale jelikož to plnění trvá dlouho, tak jsem se dostal zatím na číslo 3 miliónů řádků a vyzkoušel dobu za kterou je to schopné provést
SELECT * FROM `tabulka` WHERE pod = '17'

A je to přesně to čeho se chci vyhnout.
Zobrazeny záznamy 0 - 3 (4 celkem, Dotaz zabral 19.0812 sekund)

Takže nějaké rady jak rozdělit záznamy nebo jak se k nich chovat, aby to trvalo kratší dobu?
Davex
Profil
Scorpio1337:
Proč není sloupec pod číslo? Je na něm nastavený index?
Scorpio1337
Profil
Pod mám v tabulce jako INT. V tom příspěvku to je překlep, že je v uvozovkách. Síla zvyku, ale stejně by to fungovalo.

A tak dal jsem sloupci pod index a je to o poznání svižnější. Na necelám miliónu záznamů to jsou setiny vteřiny. Uvidíme jak se to bude chovat při vyšších číslech. Nevím jak jsem na to mohl zapomenout, ale díky. :-). Ještě aby to bylo v rozumných číslech i při pár set miliónech záznamů.
Scorpio1337
Profil
Tak jsem udělal menší zátěžový test.
Jeden script přidával data do tabulky (ID, pod, text). ID je AI, pod index a text je textarea. Do pod se náhodně přidávalo číslo od 0 do 100 000.
Druhý script každých 5 vteřin po jeho načtení uložil do jiné tabulky počet řádků v první tabulce a čas, jak dlouho trvalo provést příkaz:

mysql_query("select * from tabulka where pod='" . rand(0, 100000) . "'");

Což mělo simulovat náhodné navštěvování návštěvníků portálu.
Nechal jsem to běžet až do velikosti 64 miliónů, asi 24 hodin. Data jsem pak odfiltroval, protože podle toho jestli náhodné číslo už bylo catchované nebo ne, tak doba byla hodně rozdíná, a vytvořil graf:
http://pn.scorpio1337.com/graf.png

Na samotné údaje se můžete podívat tady:
http://pn.scorpio1337.com/data.txt

Aby portál běžel svižně, tak je asi potřeba udržet délku příkazu maximálně do 0.2s, což byla hodnota kolem 2 miliónů záznamů. Pak už to šlo pomalu nahoru do časů, které asi nebyly nejvhodnější.

Takže jaký systém rozložení databáze byste prosím doporučovali? Určitě tu s podobně velkým projektem někdo má zkušenosti.

Děkuji.
Davex
Profil
Scorpio1337:
Aby portál běžel svižně, tak je asi potřeba udržet délku příkazu maximálně do 0.2s, což byla hodnota kolem 2 miliónů záznamů.
Výsledky se mi moc nelíbí. Vyhledání v 5 milionech záznamů mi na notebooku trvá průměrně 67 ms a v 10 milionech průměrně 120 ms (4× lepší než u tebe). Ale měl jsem asi méně dat než ty, protože po přidání více textu se časy výrazně zhoršují a souvisí to také ↓.

Nechal jsem to běžet až do velikosti 64 miliónů
Pokud jsi simuloval 64 milionů diskusních příspěvků pro 100 tisíc článků, tak vychází 640 příspěvků na článek načtených z databáze najednou, což moc o realitě nevypovídá. Měl bys brát v úvahu jen čas potřebný k získání jednoho záznamu.

Pomalost nebude ani tak způsobena velikostí tabulky, ale může za to velké množství čtených záznamů. Když se databáze nevejde do paměti, tak narážíš na to, že disk provádí v náhodných datech random seek, který vychází v extrémním případě pro každý záznam asi 30 ms (20 s / 650 příspěvků), a to odpovídá běžnému disku.
Scorpio1337
Profil
Předpokládám, že by to časem mohlo dosáhnout 100 tisíc uživatelů a každý dá průměrně 100 příspěvků a až na ně bude 100 komentářů. Takže to jsme na miliardě záznamů. Ale to je teď jedno.
Snad všichni, kterých jsem se ptal mi řekli, že nemá moc smysl rozdělovat to na desítky až stovky tabulek, ale že mám raději mít jednu tabulku a optimalizovat ji podle Indexů, catchování atd. Později to přesunout na výkonější mašinu atd. I když jsem to zatím testoval na hostingu, ale i když jsem to testoval krátce na normálním serveru doma, tak výsledky byly o něco horší:
http://pn.scorpio1337.com/dddddd.png

Myslíte si, že je tato cesta (optimalizace v jedné tabulce) ideální teda?
Davex
Profil
Scorpio1337:
Domnívám se, že na jednom databázovém serveru nemá smysl rozdělovat jeden typ souvisejících záznamů do víc tabulek nebo databází. Všechno to bude brzdit disk, takže se musí použít jiné optimalizační techniky.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0