Sono un principiante ammesso all'API Entity, ma sto cercando di risolverlo. Sto lavorando su un sito che utilizza numerosi tipi di contenuto con vari campi ad essi collegati; nulla di bello. Quindi, quando voglio recuperare una serie di voci, nella mia ignoranza ho chiamato direttamente nel database e fatto qualcosa del genere:
$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();
(sì, probabilmente potrei comprimere un mucchio di queste righe in una singola $the_questions->
affermazione; per ora ignoralo.)
Cercando di riscriverlo con EntityFieldQuery, mi viene in mente:
$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();
}
che mi dà i risultati desiderati ed è sicuramente molto più bello.
Quindi, ora mi chiedo delle prestazioni. Come inizio, lancio ciascuno di quei frammenti di codice in uno stupido for()
loop, catturando time()
prima e dopo l'esecuzione. Eseguo ogni versione 100 volte su un database non molto grande e ottengo qualcosa del genere:
- Versione diretta: 110 msec
- Versione EFQ: 4943 msec
Ovviamente ottengo risultati diversi quando rieseguo il test, ma i risultati sono coerentemente nello stesso campo di baseball.
Yikes. Sto facendo qualcosa di sbagliato qui, o è solo il costo dell'utilizzo di EFQ? Non ho effettuato alcuna speciale ottimizzazione del database rispetto ai tipi di contenuto; sono solo ciò che deriva dalla definizione dei tipi di contenuto nel solito modo basato sui moduli. qualche idea? Il codice EFQ è decisamente più pulito, ma non credo proprio di potermi permettere un successo di prestazioni 40x.
->addTag('node_access')
nella query ??). Ripeto la query "diretta" con un tag node_access e i tempi di esecuzione sono molto più vicini: il tempo di EFQ ora è solo circa un fattore 2 maggiore dell'approccio diretto, che sembra ragionevole dato il relativo SQL che entrambi stanno pompando (che Posso pubblicare se alle persone interessa ancora). (proseguendo sul prossimo commento ....)