Impostare in maniera efficiente i permalink

Avvertenza

La gestione dei permalink è stata notevolmente migliorata a partire da WordPress 3.3, per cui queste informazioni risultano obsolete. In termini assoluti, avere un valore numerico in testa al permalink dà prestazioni migliori; ma in termini pratici le differenze di performance tra l’avere un valore numerico e non averlo sono irrisorie se non addirittura inesistenti. Per informazioni dettagliate su come funzionano i permalink in WordPress 3.3 e versioni successive è utile il post di Otto.

wordpress-logo

Circa un mese fa è nata una interessante discussione nel forum di WordPress relativa a un elevato e insolito numero di query al database (più di 2.000) ogni volta che si apriva una pagina di un determinato sito. La discussione si è portata avanti tra segnalazione nel Trac di WordPress, discussione in mailing-list e aggiunte al Codex, nonché su blog importanti come quello di Dougal Campbell (da cui questo articolo trae spunto). Credo sia utile far conoscere quanto si è discusso per nostra informazione e annotazione.

Il problema

Un utente di WordPress lamentava, come già detto, un elevato numero di query per ogni pagina aperta del suo sito, causando un rallentamento eccessivo; la navigazione era possibile, ma in modo molto lento e fastidioso. Su questo sito, che contava tantissime pagine e con svariati allegati, aveva tentato di tutto, disattivando qualsiasi plugin, rimettendo il tema standard e provando addirittura un hosting diverso (in locale). Il risultato fu che le query continuavano ad essere sempre le stesse. L’utente aprì quindi una discussione sul forum e, dopo qualche scambio di informazioni, si giunse alla conclusione che il problema era dovuto alla sua struttura dei permalink. Questa era del tipo /%category%/%year%/%monthnum%/%day%/%postname%/.

Come WordPress preleva gli articoli

Come sapete, WordPress è molto flessibile nella gestione dei permalink: fornisce all’utente la possibilità di poterla impostare come vuole lui, secondo i suoi gusti e le sue esigenze: %year%, %monthnum%, %day%, %hour%, %minute%, %second%, %postname%, %post_id%, %category%, %tag%, e %author%, combinandoli come meglio crede.

Per blog e siti di piccole dimensioni, una impostazione non proprio efficiente dei permalink non causa alcun problema di navigazione e, per restare nel problema al centro dell’articolo, non causa alcun rallentamento. Ma quando si ha davanti un sito con moltissime pagine statiche (intendo le pagine staccate rispetto al flusso temporale degli articoli), con tantissimi allegati, tantissimi post (quindi un sito molto “grande”) e una struttura dei permalink del tipo /%category%/%postname%/ oppure anche solo /%postname%/, allora il discorso cambia radicalmente. WordPress, infatti, davanti a questo materiale e con questi permalink fatica a trovare quello che si vuole. Vediamo perché. Per spiegarlo utilizzo lo stesso esempio che Otto ha usato nella discussione in mailing-list (metto in blockquote il testo, ma è una mia interpretazione libera del suo testo e non una traduzione).

Consideriamo un permalink del tipo /%category%/%postname%/. Un visitatore arriva nel blog cercando la pagina “mycat/mypost/”. Per noi è immediatamente comprensibile di cosa si tratta, ma non per WordPress, il quale inizia ad analizzare queste due voci.

Inizia con “mycat” e indaga su cosa sia. Dapprima si accerta se sia una pagina ed interroga il database: esiste nella tabella “wp_posts” un “post_slug” che ha “mycat” con “post_type” uguale a “page” (select from wp_posts where post_slug = mycat and post_type = page)? No, non esiste.

Quindi, tenta di vedere se “mycat” è una categoria. Esiste in “wp_terms” e (join) “wp_term_taxonomy” qualcosa in cui “term” è “mycat” e “taxonomy” è “category” (select from wp_terms join wp_term_taxonomy on (term_id = term_id) where term = mycat and taxonomy = category)? Si esiste. Ottimo, ma c’è un problema: è solo una categoria, non è il post che stiamo cercando. Passiamo oltre e ignoriamo la categoria.

WordPress lascia perdere, quindi, “mycat” e passa a “mypost”. E ricomincia la tiritera delle interrogazioni.

  1. È una pagina (select from wp_posts where post_slug = mypost and post_type = page)? No.

  2. È una categoria (select from wp_terms join wp_term_taxonomy on (term_id = term_id) where term = mypost and taxonomy = category)? No.

  3. È un post (select from wp_posts where post_slug = mypost and post_type = post)? Sì. Bingo!

Da questo si capisce quanto le categorie (ad inizio permalink) non aiutino a determinare la natura di ciò che si sta cercando. Sono state eseguite ben cinque query (delle quali due molto dispendiose, join) solo per capire quale sia il post. E ciò avviene ogni volta che si vuole visualizzare un post sul vostro sito.

Otto, in risposta al thread Wordpress scaling problems, 29 gennaio 2009.

Immaginiamo, quindi, cosa succede quando un sito sia molto esteso e abbia tantissime visite ogni secondo. Per questo motivo WordPress, per evitare tali problemi quando rileva che la nostra struttura dei permalink non è efficiente, genera delle regole di reindirizzamento (rewrite_url) per ogni cosa scriviate (post, pagina, attachment), cui ricorre ogni volta che viene richiesta una pagina del sito (che sia un post o altro). Queste regole di reindirizzamento, però, crescono a dismisura quando il sito è enorme, quando ci sono tantissime pagine statiche e relativi attachment (era il caso dell’utente di poco fa). Questa tabella può crescere così tanto da causare problemi alla navigazione.

Qual è, allora, la migliore impostazione dei permalink?

Se “migliore” lo intendiamo in termini di efficienza, senza dubbio essa consiste nell’usare come primo elemento del permalink un valore numerico (%year%, %monthnum%, %day%, %hour%, %minute%, %second% e %post_id%) o addirittura la struttuta standard miosito.com/?p=123 (che presenta altre problematiche, ma non in termini di efficienza). I problemi sorgono quando si mette come primo elemento un valore testuale come %postname%, %category%, %tag%, e %author%: in questo caso WordPress o esegue tutta quella tiritera o deve impostarsi delle regole di reindirizzamento: entrambi i sistemi sono comunque dispendiosi in termini di risorse.

Se il vostro sito/blog rientra nelle caratteristiche dette prima, rivedete i vostri permalink. Se avete un piccolo blog non preoccupatevi di nulla e usate pure la struttura che più vi piace.

Anche nel Codex è stato inserito, dopo la discussione in mailing-list, questo avviso:

For performance reasons, it is not a good idea to start your permalink structure with the category, tag, author, or postname fields. The reason is that these are text fields, and using them at the beginning of your permalink structure it takes more time for WordPress to distinguish your Post URLs from Page URLs (which always use the text “page slug” as the URL), and to compensate, WordPress stores a lot of extra information in its database (so much that sites with lots of Pages have experienced difficulties). So, it is best to start your permalink structure with a numeric field, such as the year or post ID. See wp-testers discussion of this topic.

La situazione di questo blog

Ubuntu block notes ha adottato per molto tempo la struttura /%category%/%postname%/, perché la ritengo ottima da punto di vista “umano”: si capisce subito sotto quale categoria si trova quell’articolo. Ma per i motivi su esposti ho cambiato la struttura utilizzandone una molto simile: /%year%/%category%/%postname%/, inserendo quindi un valore numerico all’inizio.

table-weight

La differenza di peso dei due file contenenti le regole, prima e dopo la “cura”.

Prima di effettuare il cambio, però, ho dato un’occhiata al database per vedere cosa avessi nella tabella wp-options > rewrite_rules. Stentavo a crederci: quasi 2.000 linee di regole! Dopo il cambio dei permalink, ho rivisitato la tabella e le righe sono scese a 200, cioè un decimo! E pensare che questo blog è piccolo: attualmente 310 articoli, 26 pagine, 12 categorie e 361 tag (ma non so quanti attachment). È evidente che WordPress ringrazia e con lui il server su cui gira.

Per approfondire date un’occhiata anche agli interessanti commenti all’articolo di Dougal, dove gli utenti pongono domande su dubbi che probabilmente potranno sorgere a chi ha letto quest’articolo.

Update

Ho preparato un diagramma di flusso per capire quando è il momento di cambiare la struttura dei permalink con una più efficiente:

wordpress-permalink

Fare clic per ingrandire