Tôi là một người mới thừa nhận API thực thể, nhưng tôi đang cố gắng khắc phục điều đó. Tôi đang làm việc trên một trang web sử dụng một số loại nội dung với các trường khác nhau được đính kèm; không có gì lạ mắt. Vì vậy, khi tôi muốn lấy một tập hợp các mục, tôi đã, trong sự thiếu hiểu biết của mình, gọi trực tiếp vào cơ sở dữ liệu và làm một cái gì đó như thế này:
$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();
(vâng, tôi có thể có thể thu gọn một loạt các dòng này thành một $the_questions->
câu lệnh; xin vui lòng bỏ qua điều đó ngay bây giờ.)
Cố gắng viết lại điều này với EntityFieldQuery, tôi nghĩ ra:
$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();
}
mang lại cho tôi kết quả mong muốn và chắc chắn là đẹp hơn nhiều.
Vì vậy, bây giờ tôi đang tự hỏi về hiệu suất. Khi bắt đầu, tôi ném từng đoạn mã đó vào một for()
vòng lặp ngu ngốc , thu giữ time()
trước và sau khi thực hiện. Tôi chạy mỗi phiên bản 100 lần trên một cơ sở dữ liệu không lớn lắm và nhận được một cái gì đó như thế này:
- Phiên bản trực tiếp: 110 msec
- Phiên bản EFQ: 4943 msec
Rõ ràng tôi nhận được kết quả khác nhau khi tôi chạy lại bài kiểm tra, nhưng kết quả luôn nằm trong cùng một sân bóng.
Rất tiếc. Tôi đang làm gì đó sai ở đây, hay đây chỉ là chi phí sử dụng EFQ? Tôi chưa thực hiện bất kỳ điều chỉnh cơ sở dữ liệu đặc biệt nào liên quan đến các loại nội dung; chúng chỉ là những gì xuất phát từ việc xác định các loại nội dung theo cách thông thường, dựa trên hình thức. Có suy nghĩ gì không? Mã EFQ chắc chắn sạch hơn, nhưng tôi thực sự không nghĩ rằng mình có thể đủ khả năng đạt hiệu suất 40 lần.
->addTag('node_access')
trong truy vấn ??). Tôi chạy lại truy vấn "trực tiếp" bằng thẻ node_access và thời gian thực hiện gần hơn rất nhiều: Thời gian của EFQ chỉ bằng khoảng 2 lần so với cách tiếp cận trực tiếp, có vẻ hợp lý với SQL tương đối mà cả hai đang bơm ra (mà Tôi có thể đăng nếu mọi người vẫn quan tâm). (tiếp theo bình luận tiếp theo ....)