Ich bin ein zugelassener Neuling in der Entity-API, aber ich versuche, das zu heilen. Ich arbeite an einer Site, die eine Reihe von Inhaltstypen mit verschiedenen Feldern verwendet. Nichts Besonderes. Wenn ich also eine Reihe von Einträgen abrufen möchte, habe ich in meiner Unwissenheit direkt in die Datenbank aufgerufen und so etwas getan:
$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();
(Ja, ich könnte wahrscheinlich ein paar dieser Zeilen zu einer einzigen $the_questions->
Anweisung zusammenfassen. Bitte ignorieren Sie dies vorerst.)
Beim Versuch, dies mit EntityFieldQuery neu zu schreiben, habe ich Folgendes gefunden:
$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();
}
Das gibt mir die gewünschten Ergebnisse und ist sicherlich viel schöner.
Jetzt wundere ich mich über die Leistung. Zunächst werfe ich jedes dieser Codebits in eine blöde for()
Schleife und nehme sie time()
vor und nach der Ausführung auf. Ich führe jede Version 100 Mal über eine nicht sehr große Datenbank aus und erhalte so etwas:
- Direkte Version: 110 ms
- EFQ-Version: 4943 ms
Natürlich erhalte ich unterschiedliche Ergebnisse, wenn ich den Test erneut durchführe, aber die Ergebnisse befinden sich durchweg im selben Bereich.
Huch. Mache ich hier etwas falsch oder sind dies nur die Kosten für die Verwendung von EFQ? Ich habe keine spezielle Datenbankoptimierung in Bezug auf die Inhaltstypen durchgeführt. Sie sind genau das, was sich aus der Definition der Inhaltstypen auf die übliche, formularbasierte Weise ergibt. Irgendwelche Gedanken? Der EFQ-Code ist definitiv sauberer, aber ich glaube wirklich nicht, dass ich mir einen 40-fachen Leistungseinbruch leisten kann.
->addTag('node_access')
die Abfrage keine enthält ??). Ich habe die "direkte" Abfrage mit einem node_access-Tag erneut durchgeführt, und die Ausführungszeiten sind viel näher: Die Zeit von EFQ ist jetzt nur um den Faktor 2 größer als der direkte Ansatz, der angesichts der relativen SQL, die beide auspumpen (was vernünftig erscheint), vernünftig erscheint Ich kann posten, wenn sich die Leute noch darum kümmern. (Fortsetzung beim nächsten Kommentar ....)