Pracuji na aplikaci, která zahrnuje mnoho zápisů do databáze, přibližně ~ 70% příloh a 30% čtení. Tento poměr by také zahrnoval aktualizace, které považuji za jedno čtení a jedno psaní. Pomocí příkazů insert vkládá více klientů data do databáze pomocí příkazu insert níže:
$mysqli->prepare("INSERT INTO `track` (user, uniq_name, ad_name, ad_delay_time ) values (?, ?, ?, ?)");
Otázkou je, zda mám použít buď insert_delay nebo použít mysqli_multi_query mechanismus, protože insert příkaz využívá ~ 100% CPU na serveru. Používám motor InnoDB ve své databázi, takže vložení zpožděné není možné. Vložení na server je ~ 36k/h a 99,89% přečteno, také jsem pomocí příkazu SELECT tam načíst data sedmkrát v jediném dotaz , tento dotaz trvá 150 sekund na serveru k provedení. Jakou techniku nebo mechanismus mohu použít pro tento úkol? Paměť mého serveru je 2 GB, měla bych rozšířit paměť ?. Podívejte se na tento problém, jakýkoli návrh mi bude vděčný.
Struktura tabulky:
+-----------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(100) | NO | | NULL | |
| uniq_name | varchar(200) | NO | | NULL | |
| ad_name | varchar(200) | NO | | NULL | |
| ad_delay_time | int(11) | NO | | NULL | |
| track_time | timestamp | NO | MUL | CURRENT_TIMESTAMP | |
+-----------------+--------------+------+-----+-------------------+----------------+
Moje databáze je v aktuálním stavu, zobrazuje 41 kB vložení (zápisů), což je pro moji databázi velmi pomalé.
Protože máte více zápisů a pak přečte, rád bych doporučil následující
Protože InnoDB nepodporuje INSERT DELAYED , použití velkého fondu vyrovnávacích pamětí InnoDB je nejbližší věcí, kterou můžete získat INSERT DELAYED. Všechny DML (INSERTs, UPDATE a DELETE) budou ukládány do mezipaměti ve fondu vyrovnávacích pamětí InnoDB. Transakční informace pro Zápisy jsou okamžitě zapsány do Redo Logů (ib_logfile0, ib_logfile1). Zápisy, které jsou zaúčtovány ve fondu vyrovnávacích pamětí, jsou periodicky vyprazdňovány z paměti na disk prostřednictvím ibdata1 (InsertBuffer pro sekundární indexy, vyrovnávací paměť Double Write). Čím větší je fond vyrovnávacích pamětí, tím větší množství INSERTů lze uložit do mezipaměti. V systému s 8 GB nebo více paměti RAM použijte 75-80% z hodnoty RAM jako innodb_buffer_pool_size. V systému s velmi malou pamětí RAM 25% (pro přizpůsobení operačního systému)).
CAVEAT: Můžete nastavit innodb_doublewrite na 0 pro zrychlení zápisu více, ale s rizikem integrita dat. Můžete také urychlit věci nastavením innodb_flush_method na O_DIRECT, abyste zabránili ukládání InnoDB do OS do mezipaměti.
Ve výchozím nastavení jsou protokoly opakování pojmenovány ib_logfile0 a ib_logfile1 a každý by měl být 5 MB. Velikost by měla být 25% velikosti innodb_buffer_pool_size. Pokud již existují nové protokoly, přidejte nové nastavení do my.cnf, vypněte mysql, odstraňte je a restartujte mysql .
Vyrovnávací paměť protokolu obsahuje změny v RAM před jejich propláchnutím do opakovacích protokolů. Výchozí hodnota je 8 M. Čím větší je vyrovnávací paměť protokolu, tím méně diskového vstupu/výstupu. Buďte opatrní při velmi velkých transakcích, protože to může zpomalit COMMITs o milisekundy.
MySQL 5.5 a MySQL 5.1 InnoDB Plugin mají nastavení umožňující přístup InnoDB Storage Engine k více procesorům. Zde jsou možnosti, které musíte nastavit:
Pokud máte MySQL 5.0, upgradujte na MySQL 5.5. Pokud máte MySQL 5.1.37 nebo starší, upgradujte na MySQL 5.5. Pokud máte MySQL 5.1.38 nebo vyšší a chcete zůstat v MySQL 5.1, nainstalujte si zásuvný modul InnoDB. Tímto způsobem můžete využít všech procesorů pro InnoDB.
INT (2) stále používá 4 bajty - možná jste mysleli TINYINT UNSIGNED?
Kolik různých hodnot v setno? Pokud je malý, KEY (setno) nebude nikdy použit. INSERTing musí tento index aktualizovat; odebrání KEY některé zrychlí.
CHAR (10) - Je flag
vždy 10 znaků? A v utf8? Možná byste mohli použít příznak VARCHAR (10) CHARACTER SET ascii
Dávejte své přílohy - 100 najednou poběží 10krát rychleji. (Více než 100 se dostává do „klesajících výnosů“.)
Jaká je hodnota autocommit? Zabalujete všechny VLOŽKY do ZAČÁTEK ... PŘIPOJIT? Jaká je hodnota innodb_flush_log_at_trx_commit?
Nastavit frontu. Aplikace se zapisuje do řádku 1 ve frontě najednou a poté vyjme řádky a vloží do databáze v dávce na základě počtu řádků na množství času, který uplynul od posledního vložení.
Viděl jsem, kde je dávkování vložek 10 000 najrychlejší, takže byste museli vyzkoušet, abyste našli sladké místo.
Mohli byste si vytvořit svůj vlastní jednoduchý systém front nebo použít existující. Zde je několik příkladů: HornetQ a File :: Queue . Zde je příspěvek na SE se seznamem dalších dobrých možností: Fronty zpráv v Perlu, php, python .