Soy un novato admitido en la API de Entity, pero estoy tratando de curar eso. Estoy trabajando en un sitio que usa varios tipos de contenido con varios campos adjuntos; nada sofisticado. Entonces, cuando quiero recuperar un conjunto de entradas, he estado, en mi ignorancia, llamando directamente a la base de datos y haciendo algo como esto:
$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í, probablemente podría colapsar un montón de estas líneas en una sola $the_questions->
declaración; por favor, ignore eso por ahora).
Intentando reescribir esto con EntityFieldQuery, se me ocurre:
$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();
}
lo que me da los resultados deseados y seguramente es mucho más bonito.
Entonces, ahora me pregunto sobre el rendimiento. Como comienzo, lanzo cada uno de esos bits de código en un for()
bucle estúpido , capturando time()
antes y después de la ejecución. Ejecuto cada versión 100 veces sobre una base de datos no muy grande, y obtengo algo como esto:
- Versión directa: 110 ms
- Versión EFQ: 4943 ms
Obviamente obtengo resultados diferentes cuando vuelvo a ejecutar la prueba, pero los resultados están consistentemente en el mismo estadio.
Yikes ¿Estoy haciendo algo mal aquí, o es solo el costo de usar EFQ? No he realizado ningún ajuste especial de la base de datos con respecto a los tipos de contenido; son justo lo que viene de definir los tipos de contenido de la forma habitual basada en formularios. ¿Alguna idea? El código EFQ es definitivamente más limpio, pero realmente no creo que pueda permitirme un éxito de rendimiento 40x.
->addTag('node_access')
en la consulta ??). Volví a realizar la consulta "directa" con una etiqueta node_access, y los tiempos de ejecución están mucho más cerca: el tiempo de EFQ ahora es solo un factor 2 mayor que el enfoque directo, lo que parece razonable dado el SQL relativo que ambos están bombeando (que Puedo publicar si a la gente todavía le importa). (continúa en el siguiente comentario ...)