Sou um novato admitido na API de entidades, mas estou tentando curar isso. Estou trabalhando em um site que usa vários tipos de conteúdo com vários campos anexados a eles; nada chique. Portanto, quando quero recuperar um conjunto de entradas, na minha ignorância, liguei diretamente para o banco de dados e fiz algo assim:
$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();
(sim, eu provavelmente poderia recolher várias dessas linhas em uma única $the_questions->
declaração; por favor, ignore isso por enquanto.)
Tentando reescrever isso com EntityFieldQuery, eu venho com:
$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();
}
o que me dá os resultados desejados e é certamente muito mais bonito.
Então, agora estou me perguntando sobre desempenho. Para começar, jogo cada um desses bits de código em um for()
loop estúpido , capturando time()
antes e depois da execução. Eu executo cada versão 100 vezes em um banco de dados não muito grande e obtenho algo assim:
- Versão direta: 110 ms
- Versão EFQ: 4943 ms
Obviamente, obtenho resultados diferentes quando refiz o teste, mas os resultados estão consistentemente no mesmo estádio.
Caramba. Estou fazendo algo errado aqui, ou isso é apenas o custo do EFQ? Eu não fiz nenhum ajuste especial no banco de dados com relação aos tipos de conteúdo; são exatamente o que vem da definição dos tipos de conteúdo da maneira usual e baseada em formulários. Alguma ideia? O código EFQ é definitivamente mais limpo, mas eu realmente não acho que posso pagar um desempenho de 40x.
->addTag('node_access')
na consulta ??). Eu redireciono a consulta "direta" com uma tag node_access, e os tempos de execução são muito mais próximos: o tempo do EFQ agora é apenas um fator 2 maior que a abordagem direta, o que parece razoável, considerando o SQL relativo que ambos estão produzindo (o que Posso postar se as pessoas ainda se importam). (continua na próxima comentário ....)