Todo lo relacionado a Internet, Programación y Tecnología

Reducir peticiones a la base de datos MySQL WordPress

Esta entrada forma parte del conjunto Optimizar WordPress reduciendo consumo de memoria, peticiones y consultas a MySQL. Para llevar a cabo esto primero debemos saber que es lo que necesitamos y que es lo que no necesitamos.

Si estamos utilizando campos personalizados

Si es posible, en lugar de utilizar muchos Campos personalizados (Post Meta) hay que utilizar solo uno pero con muchos datos. Nivel: Avanzado. WordPress tiene la capacidad de guardar Arrays (matrices o conjuntos de datos) de datos en un solo campo personalizado: Para generar los datos (functions.php o en donde tengamos nuestro Meta Box):

// Es importante el uso de true en le último parámetro.
// Este código se podría colocar en el lugar donde necesitamos mostrar los datos.
$primer_dato = 'Contenido del primer dato personalizado dentro de un array.';
$imagen = 'http://www.example.com/wp-content/images/imagen.png';
$meta_value = array(
    'primer_dato' => $primer_dato,
    'imagen' => $imagen
);
update_post_meta($post_id, 'datos_array', $meta_value);

// Esto nos devolverá un solo dato.
echo $meta_values['primer_dato'];

Para obtener los datos:

// Es importante el uso de true en le ultimo parámetro.
// Este código se podría colocar en el lugar donde necesitamos mostrar los datos.
$meta_values = get_post_meta($post_id, 'datos_array', true);

// Esto nos devolverá un solo dato.
echo $meta_values['primer_dato'];

Reducir una petición de forma sencilla (experimental)

Nivel: Avanzado, Experimental. Otra forma de reducir una petición es colocar el siguiente código en nuestro functions.php:

function my_posts_request_filter( $input = false ) {
return $input;
}
add_filter( 'posts_request', 'my_posts_request_filter' );

Nota: Es importante realizarlo con precaución y teniendo en cuenta que no se puede utilizar el filtrado de posts por medio de la función query_posts(), de lo contrario no funcionara y solo obtendrán un error SQL, y en su lugar hay que utilizar la clase WP_Query.

Forma correcta de realizar peticiones SQL

Nivel:Medio. Algo que también es muy importante realizar, es cuando tenemos peticiones MySQL personalizadas. Esto funciona guardando el contenido de una petición dentro de una variable, de tal forma que al mostrar le contenido de la misma variable varias veces, no se ejecutaran peticiones innecesarias como se realizarían si llamáramos directamente a la función cada vez que queremos obtener el mismo dato.

// El código no importa. Es solo un ejemplo.
$id = 350;
function funcion($id) {
$sql = 'SELECT * FROM wp_posts WHERE ID = $id';

return conectar($sql);
}
echo funcion($id);
// Si se hace de esta forma, cada que obtengamos el dato se realizara una petición nueva a la base de datos.

Optimizado con variables:

// El código no importa. Es solo un ejemplo.
$id = 350;
function funcion($id) {
$sql = 'SELECT * FROM wp_posts WHERE ID = $id';

return conectar($sql);
}
$post = funcion($id);

echo $post;
// Si se hace de esta forma, cada que obtengamos el dato se mostrara el contenido de la variable $post que previamente se estableció.

Usando el API de Transients de WordPress

Nivel: Avanzado. Otra forma distinta y muy útil es utilizando los Transients de WordPress. Los Transients son datos que se guardan en una tabla de WordPress donde se genera una petición para cargar todas las opciones de WordPress, y lo que se puede cachear en ese lugar son por ejemplo los widgets y elementos que solo se muestran en la página principal y no lo recomiendo en los posts individuales porque al momento de tener muchos posts WordPress cada que inicia revisa todos los datos de esta tabla y estaría consumiendo mucha memoria y consultando datos que no se necesitan. El código necesario para mostrar un post aleatorio más el sistema de Cache propio de WordPress mediante Transients:

if ( false === ( $post_aleatorio = get_transient( 'post_aleatorio' ) ) ) {
    $query_post_aleatorio = new WP_Query(array('orderby' => 'rand', 'posts_per_page' => 1));
    while ($query_post_aleatorio->have_posts()) : $query_post_aleatorio->the_post();

    $post_id_post_aleatorio = $post->ID;
    $titulo_ = get_the_title();
    $enlace_ = get_permalink();
    $imagen_ = data( 'servidor_imagenes', $post_id_post_aleatorio, true ); // Esta funcion es propia (No utilizarla).

    $post_aleatorio = <img alt="$titulo_" src="%24imagen_"><strong>$titulo_</strong>
EOT;

    endwhile;

    set_transient( 'post_aleatorio', $post_aleatorio );
}

echo $post_aleatorio;
unset($post_aleatorio);

Nota: Cuando se borra un Transient con las siguientes funciones, el Transient se vuelve a generar en la primer petición recibida. Para borrar los Transients cada que se publica un nuevo post o cada que se actualiza uno existente:

function delete_publish_post_transients() {
    delete_transient( 'post_aleatorio' );
}
add_action('publish_post','delete_publish_post_transients');

Nota:set_transient() acepta tres parámetros, de los cuales el tercero es para especificar una caducidad establecida en segundos, la cual no recomiendo utilizar porque el simple hecho de utilizarla le quita la opción para que cargue automáticamente junto con las demás opciones de WordPress y se crearía una petición extra a la base de datos y esto no es lo que estamos buscando aunque nos podría ser útil en otros casos.

Para borrar el Transient cada cierto tiempo (En el ejemplo cada hora):

add_action('hourly_delete_transients', 'delete_post_aleatorio');

function tarea_eliminar_post_aleatorio() {
    if (!wp_next_scheduled( 'hourly_delete_transients' ) ) {
        wp_schedule_event(time(), 'hourly', 'hourly_delete_transients');
    }
}
add_action('wp', 'tarea_eliminar_post_aleatorio');

function delete_post_aleatorio() {
    delete_transient( 'post_aleatorio' );
}

Parece un poco complicado pero una ves dominado puede ser de gran ayuda para mejorar el rendimiento de nuestros sitios.

Escrito por Alan en 2018-02-10 23:46:42 UTC

Enlace permanente - categoría: WordPress

« Optimizar WordPress reduciendo consumo de memoria, peticiones y consultas a MySQL - Ajustando WordPress para mejorar el rendimiento wp-config.php »