Pregunta:
Estoy trabajando en un sitio web para una empresa que probablemente creará millones de publicaciones a través de un tipo de publicación personalizada. Son oraciones, por lo que básicamente el usuario en la interfaz solo envía una frase corta a través de un formulario. Lo único que le importa a la empresa es el contenido de la publicación y la fecha de publicación. El sitio ni siquiera se ha lanzado todavía y ya tienen más de 120.000 publicaciones, así que hablo en serio cuando digo millones.
Entonces, un par de preguntas de optimización:
- Digamos que tengo una categoría 'destacada' en un tipo de publicación personalizada que tiene 500,000 publicaciones. La categoría destacada solo tiene 500 publicaciones. Si creo una consulta para las publicaciones destacadas, ¿estoy consultando las 500.000 publicaciones completas o solo las 500 destacadas? ¿Qué pasa si solo quiero mostrar las diez publicaciones más recientes que aparecen?
- Al guardar este tipo de publicación personalizada en la base de datos, ¿hay algo que pueda hacer para reducir los recursos del servidor, especialmente porque lo único que realmente se necesita es el contenido de la publicación y la fecha?
- ¿Debería incluso usar un tipo de publicación personalizada? En principio, me gusta porque está bien integrado en el administrador de WordPress, pero si hay desventajas significativas en el rendimiento, supongo que puedo hacer algo diferente.
Nunca he trabajado en un proyecto a esta escala, así que estoy un poco más preocupado por el rendimiento que de costumbre. ¡Gracias por cualquier ayuda!
Respuesta:
1. Configure la consulta antes de que se ejecute WP_Query
Esto parece ser lo más importante a tener en cuenta cuando se intenta mantener al mínimo las consultas de la base de datos, ya que la única oportunidad de modificar la consulta es, por supuesto, antes de que se ejecute en la base de datos SQL.
Consultas normales
Para una consulta normal, WordPress usa la función wp()
, que a su vez llama a $wp->main( $query_vars )
. Las "is_ variables" de las etiquetas condicionales se establecen antes de pasarlas a WP_Query->get_posts()
, que las convierte en una consulta de base de datos MySQL y finalmente las almacena en el objeto $ wp_query. Es posible filtrar la consulta antes de que se ejecute realmente en la base de datos SQL .
La acción pre_get_posts
conecta a este proceso, lo que le permite cambiar la consulta antes de que se pase a WP_Query->get_posts()
.
Por ejemplo, si desea filtrar la consulta por publicaciones en la categoría "destacados", debe usar add_action( 'pre_get_posts', 'your_function_name' );
e incluir el in_category
etiqueta condicional dentro your_function_name
.
function your_function_name( $query ) {
if ( $query->in_category( 'featured' ) && $query->is_main_query() ) {
// Replace 123 with the category ID of the featured category.
$query->set( 'cat', '123' );
}
}
add_action( 'pre_get_posts', 'your_function_name' );
Ver Plugin API / Action Reference / pre get posts «WordPress Codex
Solicitudes de página
En cuanto a las plantillas de página, como la página de archivo de la categoría "destacados", las etiquetas condicionales no funcionarán desde el filtro pre_get_posts
. Por ejemplo, no puede usar is_category
para buscar la página de archivo porque WP_Query no se ha ejecutado.
En su lugar, tendría que modificar la consulta principal para solicitudes de página con un new WP_Query
que se vería algo así como $query = new WP_Query( 'cat=123' );
. Esto ejecuta la consulta con el argumento apropiado establecido desde el principio.
Ver Referencia de clase / Consulta WP «Códice de WordPress
2. Guardar en la base de datos
Puede usar el filtro wp_insert_post_data
asegurándose de que solo los $ datos relevantes para su tipo de publicación personalizada se devuelvan a wp_insert_post
. Asegúrese de incluir una declaración condicional para verificar su tipo de publicación personalizada.
Complemento API / Referencia de filtro / wp insertar datos de publicación «Códice de WordPress
Este wp_insert_post
es llamado por la función wp_insert_post
, que es llamado por wp_update_post cuando actualiza su tipo de publicación personalizada, generalmente guardando un borrador o publicando la publicación.
Sin embargo, tendrá que compararlo usted mismo, ya que personalmente no puedo hablar sobre la importancia de la optimización de reducir los datos que se actualizan en la base de datos.
3. ¿Los tipos de publicaciones personalizadas afectan el rendimiento?
En mi experiencia, los tipos de publicaciones personalizadas son una herramienta poderosa para administrar contenido. No conozco ninguna otra forma de administrar las publicaciones de todas las formas en que lo permite de una manera que use menos recursos. Personalmente, me enfocaría en encontrar formas de reducir la cantidad de consultas realizadas siempre que sea posible.
Solía haber un problema de rendimiento relacionado con la estructura del enlace permanente que provocaba que recibiera un golpe cuando comenzaba con texto en lugar de un número. 3 Esto fue particularmente problemático para los sitios que albergan una gran cantidad de páginas, pero se ha resuelto desde la versión 3.3 de WordPress.
Solo menciono los enlaces permanentes aquí porque el slug suele ser la primera parte de la estructura del enlace permanente que puede o no haber afectado el rendimiento antes de la versión 3.3. Aparte de eso, no tengo conocimiento de ningún problema de rendimiento que surja del uso de tipos de publicaciones personalizadas.
Otras opciones de rendimiento
Transitorios
Esto no es un reemplazo para mantener las consultas al mínimo en su código, pero puede usar set_transient para almacenar las consultas durante algún tiempo para que no sean necesarias nuevas consultas. Aquí está el ejemplo usado en la publicación de Dave Clements . Además, tenga en cuenta que recomienda agregar una acción save_post
para eliminar el transitorio cada vez que se actualiza un tipo de publicación determinado.
<?php // IN THE SPOTLIGHT QUERY
if( false === ( $its_query = get_transient( 'its_query' ) ) ) {
$pttimestamp = time() + get_option('gmt_offset') * 60*60;
$its_query = new WP_Query( array(
'post_type' => 'spotlight',
'posts_per_page' => 1,
'post__not_in' => $do_not_duplicate,
'meta_query' => array(
array(
'key' => '_hpc_spotlight_end_time',
'value' => $pttimestamp,
'compare' => '>'
)
)
) );
set_transient( 'its_query', $its_query, 60*60*4 );
}
if( have_posts() ) { // HIDE SECTION IF NO CURRENT ITS FEATURE ?>
// LOOP GOES HERE: NOT IMPORTANT TO EXAMPLE
<?php } ?>
Más optimización de consultas
Thomas Griffin tiene algunos buenos consejos en su tutorial Optimizar consultas de WordPress . Aquí hay una breve lista de sus sugerencias:
-
Establezca
'cache_results' => false
en consultas'cache_results' => false
si su servidor no está usando almacenamiento en caché persistente como Memcached. Las consultas únicas se describen como "consultas que se utilizan para mostrar pequeñas cantidades de datos. Puede ser que solo desee mostrar títulos de publicaciones vinculadas relacionadas con la publicación actual, o puede mostrar un menú desplegable de publicaciones para seleccionar una configuración de opción particular ".Su ejemplo:
$query = get_posts( array( 'posts_per_page' => 1, 'cache_results' => false ) );
-
Establezca
'no_found_rows' => true
donde la paginación no es necesaria. Esto "evitará que MySQL cuente los resultados para ver si necesitamos paginación o no".Su ejemplo:
$query = new WP_Query( array( 'posts_per_page' => 1, 'no_found_rows' => true ) );
-
Consulta los ID de las publicaciones solo si esto es todo lo que necesitas
'fields' => 'ids'
enget_posts
. Esto debería reducir significativamente la cantidad de datos que se devuelven, que es bastante por publicación si observa la Descripción de la base de datos «Códice de WordPressSu ejemplo:
$query = get_posts( array( 'posts_per_page' => 1, 'fields' => 'ids' ) );
Además de ese último consejo, se puede aplicar el mismo razonamiento cuando solo necesita uno o unos pocos campos de publicación utilizando get_post_field .
Tener un conocimiento sólido de cómo funciona la consulta es esencial. Cuanto más específico pueda ser con sus consultas, menos trabajo exigirá a su base de datos SQL. Esto significa que hay una gran cantidad de posibilidades para administrar consultas de bases de datos. Tenga cuidado con las consultas personalizadas en cuanto a dónde se ejecutan (¿es una página de administración?), Use la desinfección adecuada en las consultas directas e intente usar funciones nativas de WordPress donde le permita lograr el mismo rendimiento.