Doporučení CakePHP přecházet obrovský stůl a generovat sitemap?

hlasů
6

Snažím se vytvořit XML Sitemap pomocí CakePHP, z tabulky, která má více než 50.000 záznamů v okamžiku každý záznam odpovídající URI v souboru Sitemap. Nyní je problém čelím je CakePHP mě nedostatek paměti při generování to ze dvou důvodů:

  1. find('all')Buduje obrovskou asociativní pole z celého souboru 50,000 URI.
  2. Vzhledem k tomu, nechci, aby HTML výstup z automatu, já převedení asociativní pole obsahující URI, prioritu, změna frekvence atd, k pohledu s $this->set()výzvou - což je opět obrovský, obsahující 50,000 indexy.

Je to vůbec možné, provádět tuto chvíli následující pokyny MVC a CakePHP?

Položena 03/03/2010 v 07:34
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
4

Vím, že tato otázka je stará, ale ve skutečnosti obrovské dotazy stále není dobré řešení, myslím.

Iterovat obrovské výsledný soubor můžete použít DboSource metody.

Nejprve získat DBO

$dbo = $this->Model->getDataSource();

Sestavit dotaz

$sql = $dbo->buildStatement($options);

Potom provést příkaz a iterovat výsledky

if ($dbo->execute($sql))
{
    while ($dbo->hasResult() && $row = $dbo->fetchResult()) {
        // $row is an array with same structure like find('first')
    }
}
Odpovězeno 29/02/2012 v 15:52
zdroj uživatelem

hlasů
3

Měl jsem podobný problém tento týden, a narazil do zvládnutelná chování. To vám umožní snížit případné dotazy související vztah (pokud nějaké máte).

Nejlepším řešením by bylo programově použití LIMIT a OFFSET a procházet sadu záznamů malé kousky najednou. To vám ušetří od cpát 50K záznamů do paměti najednou.

Odpovězeno 03/03/2010 v 08:34
zdroj uživatelem

hlasů
2

Jsou si jisti, že máte dostatek paměti na 50.000 záznamů? Dokonce i v případě, že řádek je 1K velikosti (docela obrovské), by se budete muset vypořádat s ~ 50 MB dat? My P1 měl dostatek paměti RAM pro práci to. Nastavit memory_limit v php.ini vyšší než výchozí. (Zvažte také vylepšování direktivy max_execution_time).

Na druhou stranu, pokud se domníváte, že se sestava údajů za příliš velký a jeho zpracování jako příliš finančně náročné, neměli byste tuto stránku sloužit dynamicky, je to ideální DDoS návnada. (Alespoň bych to mezipaměti těžce.) Ty by mohly naplánovat cronu znovu vygenerovat stránku každých X hodin od na straně serveru skript zdarma z MVC trestu sloužit všechna data najednou k názoru, mohlo by to fungovat na řádky postupně.

Odpovězeno 03/03/2010 v 21:33
zdroj uživatelem

hlasů
2

find ( ‚všechny‘) je příliš chamtiví, budete muset být konkrétnější, pokud nechcete spustit nedostatek paměti.

Jak již bylo uvedeno výše, použijte zvládnutelná chování. Pokud budete potřebovat pouze výsledky z vašeho stolu, (bez přidruženého tabulek) a jen na pár oblastí, více explicitní dotaz jako by to mělo být lepší:

$results = $this->YourModel->find('all', array(
    'contain' => false,
    'fields' => array('YourModel.name', 'YourModel.url')
);

Měli byste také zvážit přidání mechanismus html mezipaměti (CakePHP má vestavěný nebo pomocí jednoho navrhl Matt Curry ).

Samozřejmě, že to bude verze v mezipaměti a nebude zcela aktuální do svého seznamu. Pokud chcete získat větší kontrolu, můžete vždy uložit výsledek do mezipaměti dort (s použitím Cache :: write ), pomocí afterSave / afterDelete zpětná volání svého modelu aktualizovat hodnotu v mezipaměti a znovu soubor v mezipaměti XML odtud.

Odpovězeno 03/03/2010 v 14:57
zdroj uživatelem

hlasů
1

Použijte https://github.com/jamiemill/cakephp_find_batch nebo realizovat tuto logiku sami.

Odpovězeno 30/06/2012 v 19:17
zdroj uživatelem

hlasů
1

Už jste vyzkoušeli unBindModel (pokud máte vztahy) ...

Kdykoliv mám dělat obrovské dotazů v CakePHP Jen jsem používat „normální“ MySQL funkce, jako je mysql_query, mysql_fetch_assoc atd. Mnohem rychlejší, a ne nedostatek paměti ...

Odpovězeno 03/03/2010 v 07:47
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more