Jak zjednodušit databázové dotazy když nepotřebujete stránkování?

Chystaný WordPress 3.2 se zaměřuje hlavně na optimalizaci a zrychlení načítání webu a v této souvislosti byl objeven docela zajímavý trik. Jde o “neveřejný” parametr no_found_rows, který může být využit např. ve funkcích query_posts(), WP_Query() či get_posts(), ale skoro nikdo o něm neví a moc se nepoužívá, i když dokáže v mnoha případech zjednodušit některé prováděné dotazy do databáze, a tím i zrychlit načítání celého webu ve WordPressu.

Dnešní tip je určen spíše pro pokročilejší uživatele a využijete ho v případě, kdy nepotřebujete pro nějaký vlastní výpis příspěvků (vlastních typů obsahu) využívat stránkování, např. různé widgety a vlastní funkce s výpisy různých “nej”. Vysvětlení celého problému je vcelku jednoduché, zkusíme to názorně ilustrovat na konkrétním příkladu. Pokud používáte klasický web s nejnovějšími příspěvky na úvodní stránce, probíhají v pozadí obvykle dva dotazy:

SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 10

SELECT FOUND_ROWS()

Prvním dotazem je získáno 10 nejnovějších příspěvků (omezení pomocí LIMIT), ale pomocí SQL_CALC_FOUND_ROWS zároveň zjišťujeme celkový počet příspěvků splňujících podmínky bez ohledu na omezení LIMIT. Druhý dotaz pak vlastně ani není přímo klasickým dotazem do databáze, ale pouze zjištěním výsledku (celkového počtu) předchozího dotazu z databázové cache. Pokud by v prvním dotazu nebylo uvedeno SQL_CALC_FOUND_ROWS, tak by druhý dotaz vrátil hodnotu 10 (či nižší). V tomto případě ale získáme celkový počet všech příspěvků (publikovaných či soukromých), který může být dále využit např. pro stránkování.

Cílem tohoto článku není diskuze, zda je lepší řešit tento problém pomocí SQL_CALC_FOUND_ROWS a následného FOUND_ROWS() nebo dvou samostatných dotazů v podobě SELECT COUNT(*) a následného jednoduchého SELECT. Zájemci si mohou tuto problematiku detailně nastudovat (anglicky, česky). Vycházíme z toho, že WordPress používá SQL_CALC_FOUND_ROWS a musíme si s tím umět nějak poradit.

Hlavní stránka (a další, např. výpisy rubrik a štítků) musí se stránkováním pro jistotu počítat, takže je třeba SQL_CALC_FOUND_ROWS využít stávajícím způsobem. Stránkování už ale není potřeba u mnoha dalších výpisů (šablony, pluginy), kde stačí využít např. jen 10 nejnovějších příspěvků (bez odkazů na starší příspěvky či samotné stránkování) a nezajímá nás celkový počet. V tomto případě je tam tedy SQL_CALC_FOUND_ROWS zcela zbytečné a při velkém počtu příspěvků (řádově tisíce) také náročné na zpracování. Můžete tomu ale jednoduše zabránit, a to přidáním parametru no_found_rows do příslušné funkce a nastavení hodnoty true či 1 (výchozí hodnota je totiž false).

Příklad:

query_posts('posts_per_page=10&no_found_rows=true');

V tomto případě tak bude proveden pouze jednoduchý dotaz bez SQL_CALC_FOUND_ROWS:

SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 10

Ušetříte tak trochu výkonu, což je důležité zejména pro weby s velkým počtem článků a vysokou návštěvností, protože při použití SQL_CALC_FOUND_ROWS u velkých databázových tabulek vznikají tzv. “pomalé dotazy” (slow queries). Tento problém se bohužel vyskytuje i přímo ve WordPressu, kde je např. widget pro Nejnovější příspěvky zobrazován na základě zbytečně náročného dotazu na celkový počet příspěvků (bude opraveno ve WordPressu 3.2). Možná bude celý problém také vyřešen obecně a parametr no_found_rows bude využíván defaultně, ale zatím je těžké nějaké řešení předvídat.

Pokud máte malý web (řádově stovky příspěvků) a nízkou návštěvnost (desítky – stovky čtenářů denně), nemusíte tuto problematiku příliš řešit. Ostatním uživatelům však může přinést tento jednoduchý trik drobné zrychlení a ubrat trochu zbytečné práce databázovému serveru.

Nejoblíbenější hosting pro WordPress WEDOS.cz

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *