Je suis un débutant admis à l'API Entity, mais j'essaie de remédier à cela. Je travaille sur un site qui utilise un certain nombre de types de contenu avec différents champs attachés à eux; Rien d'extraordinaire. Donc, quand je veux récupérer un ensemble d'entrées, j'ai, dans mon ignorance, appelé directement dans la base de données et fait quelque chose comme ceci:
$query = db_select('node', 'n')->extend('PagerDefault');
$query->fields('n', array('nid'));
$query->condition('n.type', 'my_content_type');
$query->leftJoin('field_data_field_user_role', 'role', 'n.nid = role.entity_id');
$query->condition('role.field_user_role_value', $some_value);
$query->leftJoin('field_data_field_withdrawn_time', 'wt', 'n.nid = wt.entity_id');
$query->condition('wt.field_withdrawn_time_value', 0);
$query->orderBy('n.created', 'desc');
$query->limit(10);
$result = $the_questions->execute()->fetchCol();
(Oui, je pourrais probablement regrouper un tas de ces lignes en une seule $the_questions->
déclaration; veuillez ignorer cela pour l'instant.)
En essayant de réécrire cela avec EntityFieldQuery, je trouve:
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'my_content_type')
->fieldCondition('field_user_role', 'value', $some_value)
->fieldCondition('field_withdrawn_time', 'value', 0)
->propertyOrderBy('created', 'desc')
->pager(10);
$result = $query->execute();
if (isset($result['node'])) {
$result_nids = array_keys($result['node']);
}
else {
$result_nids = array();
}
ce qui me donne les résultats escomptés et est sûrement beaucoup plus joli.
Donc, maintenant je me pose des questions sur les performances. Pour commencer, je jette chacun de ces bits de code dans une for()
boucle stupide , capturant time()
avant et après l'exécution. J'exécute chaque version 100 fois sur une base de données pas très grande et j'obtiens quelque chose comme ceci:
- Version directe: 110 msec
- Version EFQ: 4943 msec
Évidemment, j'obtiens des résultats différents lorsque je relance le test, mais les résultats sont toujours dans le même stade.
Oui. Suis-je en train de faire quelque chose de mal ici, ou est-ce juste le coût d'utilisation de l'EFQ? Je n'ai effectué aucun réglage spécial de la base de données en ce qui concerne les types de contenu; ils sont juste ce qui vient de la définition des types de contenu de la manière habituelle, basée sur un formulaire. Des pensées? Le code EFQ est certainement plus propre, mais je ne pense vraiment pas pouvoir me permettre un rendement 40 fois supérieur.
->addTag('node_access')
dans la requête ??). J'ai relancé la requête "directe" avec une balise node_access, et les temps d'exécution sont beaucoup plus proches: le temps d'EFQ est maintenant seulement environ un facteur 2 supérieur à l'approche directe, ce qui semble raisonnable compte tenu du SQL relatif que les deux pompent (ce qui Je peux poster si les gens se soucient encore). (suite au commentaire suivant ....)