私はEntity APIの初心者ですが、それを解決しようとしています。私は、さまざまなフィールドが付加された多数のコンテンツタイプを使用するサイトで作業しています。派手なものは何もない。したがって、一連のエントリを取得したい場合、私は無知で、データベースを直接呼び出して、次のようなことをしています。
$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();
(はい、私はおそらくこれらの行の束を単一の$the_questions->
ステートメントに折りたたむことができます; plsは今のところそれを無視します。)
EntityFieldQueryでこれを書き換えようとすると、次のようになります。
$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();
}
これは私に望ましい結果を与え、確かにかなりきれいです。
だから、今、パフォーマンスについて疑問に思っています。まず、これらのコードの各ビットを愚かなfor()
ループに入れて、time()
実行の前後をキャプチャします。それほど大きくないデータベースで各バージョンを100回実行すると、次のような結果が得られます。
- 直接バージョン:110ミリ秒
- EFQバージョン:4943ミリ秒
テストを再実行すると、明らかに異なる結果が得られますが、結果は一貫して同じ範囲内にあります。
うわぁ。私はここで何か悪いことをしていますか、それともこれはEFQを使用するコストだけですか?コンテンツタイプに関して特別なデータベースチューニングは行っていません。これらは、通常のフォームベースの方法でコンテンツタイプを定義することから得られるものです。何かご意見は?EFQコードは間違いなくよりクリーンですが、40倍のパフォーマンスヒットができるとは思えません。
->addTag('node_access')
ました(クエリにない場合でも??)。node_accessタグを使用して「直接」クエリを再実行しました。実行時間ははるかに近くなっています。EFQの時間は、直接アプローチより約2倍大きいだけです。これは、両方がポンプアウトしている相対SQL(これはそれでも気になれば投稿できます)。(次のコメントで続きます...)