Je dois obtenir un tas de messages avec leurs métadonnées. Bien sûr, vous ne pouvez pas obtenir de métadonnées avec une requête de publication standard, vous devez donc généralement effectuer une recherche get_post_custom()
pour chaque publication.
J'essaie avec une requête personnalisée, comme ceci:
$results = $wpdb->get_results("
SELECT p.ID,
p.post_title,
pm1.meta_value AS first_field,
pm2.meta_value AS second_field,
pm3.meta_value AS third_field
FROM $wpdb->posts p LEFT JOIN $wpdb->postmeta pm1 ON (
pm1.post_id = p.ID AND
pm1.meta_key = 'first_field_key'
) LEFT JOIN $wpdb->postmeta pm2 ON (
pm2.post_id = p.ID AND
pm2.meta_key = 'second_field_key'
) LEFT JOIN $wpdb->postmeta pm3 ON (
pm3.post_id = p.ID AND
pm3.meta_key = 'third_field_key'
)
WHERE post_status = 'publish'
");
Semble travailler. Il se déclenche si vous utilisez l'un de ces champs méta d'une manière qui autorise plusieurs méta-valeurs pour le même poste. Je ne peux pas penser à une jointure pour faire ça.
Donc, question 1: existe-t-il une jointure, une sous-requête, ou autre, pour importer des méta-champs à valeurs multiples?
Mais question 2: ça vaut le coup? Combien de postmeta
jointures de table dois-je ajouter avant qu'une approche à 2 requêtes devienne préférable? Je pouvais saisir toutes les données de publication dans une requête, puis toutes les publications pertinentes dans une autre et combiner la méta avec les données de publication dans un jeu de résultats en PHP. Cela finirait-il par être plus rapide qu'une requête SQL de plus en plus complexe, si cela est encore possible?
Je pense toujours: "Donnez autant de travail que possible à la base de données." Pas sûr sur celui-ci!
get_posts()
, alorsget_post_meta()
pour chacun d'entre eux? @MannyFleurmond, il est difficile de trouver des informations fiables sur la mise en cache intégrée de WP, mais autant que je sache, les choses seraient mises en cache par requête. L'appel au serveur pour récupérer ces données est un appel AJAX, et je ne pense pas que rien d'autre puisse récupérer des données avant.Réponses:
Les métadonnées post sont automatiquement mises en cache dans la mémoire pour une
WP_Query
requête standard (et la requête principale), sauf si vous lui indiquez de ne pas le faire en utilisant leupdate_post_meta_cache
paramètre.Par conséquent, vous ne devriez pas écrire vos propres requêtes pour cela.
Comment fonctionne la meta-cache pour les requêtes normales:
Si le
update_post_meta_cache
paramètre àWP_Query
n'est pas défini sur false, laupdate_post_caches()
fonction sera appelée une fois les publications extraites de la base de données, puis appeléeupdate_postmeta_cache()
.La
update_postmeta_cache()
fonction est un wrapper pourupdate_meta_cache()
, et elle appelle essentiellement un simpleSELECT
avec tous les identifiants des posts récupérés. Cela lui permettra d'obtenir tout le postmeta, toutes les publications de la requête, et d'enregistrer ces données dans le cache d'objets (usingwp_cache_add()
).Lorsque vous faites quelque chose comme
get_post_custom()
, c'est d'abord vérifier ce cache d'objets. Donc, il ne faut pas faire de requêtes supplémentaires pour obtenir la publication méta à ce stade. Si vous avez le message dans unWP_Query
, alors la méta est déjà en mémoire et il l'obtient directement à partir de là.Les avantages ici sont bien plus nombreux que les requêtes complexes, mais le plus gros avantage provient de l'utilisation du cache d'objets. Si vous utilisez une solution de mise en cache de la mémoire persistante telle que XCache ou memcached, APC ou quelque chose du genre et que vous disposez d'un plug-in pouvant y lier votre cache d'objets (W3 Total Cache, par exemple), alors tout le cache d'objets est stocké en mémoire rapide. déjà. Dans ce cas, aucune requête n'est nécessaire pour récupérer vos données; c'est déjà en mémoire. La mise en cache d'objets persistants est géniale à bien des égards.
En d'autres termes, votre requête charge probablement et charge plus lentement que d'utiliser une requête appropriée et une solution simple de mémoire persistante. Utilisez la normale
WP_Query
. Épargnez-vous des efforts.Supplémentaire:
update_meta_cache()
est intelligent, BTW. Les méta-informations ne seront pas récupérées pour les publications dont les méta-informations sont déjà mises en cache. Il ne fait pas deux fois la même méta, fondamentalement. Super efficace.Additional additionnel: "Donnez le plus de travail possible à la base de données." ... Non, c'est le Web. Des règles différentes s'appliquent. En général, vous voulez toujours donner le moins de travail possible à la base de données, si cela est réalisable. Les bases de données sont lentes ou mal configurées (si vous ne les avez pas configurées spécifiquement, vous pouvez parier que cela est vrai). Souvent, ils sont partagés entre plusieurs sites et surchargés dans une certaine mesure. Vous avez généralement plus de serveurs Web que de bases de données. En général, vous souhaitez extraire les données souhaitées de la base de données aussi rapidement et simplement que possible, puis les trier à l'aide du code côté serveur Web. En règle générale, bien sûr, différents cas sont tous différents.
la source
Je recommanderais une requête pivot. En utilisant votre exemple:
la source
J'ai rencontré un cas où je veux aussi pouvoir récupérer rapidement de nombreux messages avec leurs méta-informations associées. J'ai besoin de récupérer des messages O (2000).
Je l'ai essayé en utilisant la suggestion d'Otto - exécutant WP_Query :: query pour toutes les publications, puis parcourant get_post_custom et exécutant pour chaque publication. Cela a pris en moyenne environ 3 secondes .
J'ai ensuite essayé la requête pivot d'Ethan (bien que je n'aime pas avoir à demander manuellement chaque méta_key qui m'intéressait). Il me restait encore à parcourir toutes les publications récupérées pour annuler la sérialisation de la méta_valeur. Cela a pris en moyenne environ 1,3 seconde .
J'ai ensuite essayé d'utiliser la fonction GROUP_CONCAT et j'ai trouvé le meilleur résultat. Voici le code:
Cela a pris en moyenne 0,7 seconde . C'est environ le quart du temps de la solution WP get_post_custom () et environ la moitié de la solution de requête pivot.
Cela intéressera peut-être quelqu'un.
la source
Je me suis trouvé dans une situation où je devais faire cette tâche pour créer un document CSV à partir de, j'ai fini par travailler directement avec mysql pour faire cela. Mon code rejoint les tables de méta et les tables de méta pour récupérer les informations de tarification de woocommerce. La solution précédemment publiée nécessitait que j'utilise des alias de table dans SQL pour fonctionner correctement.
Soyez averti cependant, woocommerce a créé plus de 300 000 lignes dans ma table de méta, elle était donc très grande et donc très lente.
la source
PAS DE VERSION SQL:
Obtenez tous les messages et toutes leurs méta-valeurs (métas) sans SQL:
Supposons que vous ayez une liste d’ID de publication stockés sous la forme d’un tableau d’ID, quelque chose comme:
Maintenant, obtenir tous les posts et toutes les métas dans 1 requête n'est pas possible sans utiliser au moins un peu de SQL, nous devons donc faire 2 requêtes (encore 2):
1. Obtenez tous les messages (en utilisant WP_Query )
(N'oubliez pas d'appeler
wp_reset_postdata();
si vous faites une "boucle" après;))2. Mettre à jour le méta cache
Pour obtenir les métadonnées, utilisez simplement le standard
get_post_meta()
qui, comme @Otto l'a souligné:examine d'abord le cache :)
Remarque: si vous n'avez pas réellement besoin d'autres données des articles (comme le titre, le contenu, ...), vous ne pouvez en faire que 2. :-)
la source
en utilisant la solution trevor et en la modifiant pour fonctionner avec du SQL imbriqué. Ceci n'est pas testé.
la source
J'ai aussi rencontré le problème des champs de méta de valeurs multiples. Le problème est avec WordPress lui-même. Regardez dans wp-includes / meta.php. Cherchez cette ligne:
Le problème est avec l'instruction CAST. Dans une requête de méta-valeurs, la variable $ meta_type est définie sur CHAR. Je ne connais pas les détails sur la façon dont CASTing la valeur de CHAR affecte la chaîne sérialisée, mais pour résoudre ce problème, vous pouvez supprimer la conversion de sorte que le code SQL ressemble à ceci:
Maintenant, même si cela fonctionne, vous travaillez avec les éléments internes de WordPress, ce qui pourrait entraîner des problèmes, et ce n'est pas une solution permanente, en supposant que vous ayez besoin de mettre à niveau WordPress.
La façon dont je l'ai corrigé est de copier le SQL généré par WordPress pour la méta-requête que je veux, puis d'écrire un peu de PHP pour ajouter des instructions AND supplémentaires aux méta_valeurs que je cherche et d'utiliser $ wpdb-> get_results ($ sql ) pour la sortie finale. Hacky, mais ça marche.
la source
get_meta_sql
il serait bien sûr préférable d'utiliser le filtre qui suit cette ligne plutôt que de pirater le code principal.