Tôi hiện đang cố gắng cải thiện một vài mô-đun về hiệu suất.
Một số bạn có thể biết cách sử dụng walk()
phương pháp trên bộ sưu tập rất hữu ích để tránh lặp trực tiếp qua các sản phẩm.
Trên hết và nhờ @Vinai, người ta cũng có thể sử dụng delete()
phương pháp thu thập .
Nhưng tôi nhận thấy rằng các tệp gốc Magento 1 không luôn sử dụng bất kỳ phương thức nào để xóa.
Một trong những mã tồi tệ nhất tôi thấy là massDelete()
phương thức app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
mà các sản phẩm được tải trong một vòng lặp trước khi xóa .
foreach ($productIds as $productId) {
$product = Mage::getSingleton('catalog/product')->load($productId);
Mage::dispatchEvent('catalog_controller_product_delete', array('product' => $product));
$product->delete();
}
Vì vậy, tôi đã thực hiện một số kiểm tra hiệu suất, thêm một số cuộc gọi đăng nhập để kiểm tra thời gian thực hiện và việc sử dụng bộ nhớ cho 100 sản phẩm bị xóa.
Kiểm tra 1: walk
phương pháp
Tôi đã thay thế mã gốc được dán ở trên bằng mã này:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->walk('delete');
Và kết quả của tôi là như sau trên máy chủ dev crappy của tôi (trung bình dựa trên 10 bài kiểm tra):
- Mã gốc: 19,97 giây, sử dụng 15,84 MB
- Mã tùy chỉnh: 17,12 giây, sử dụng 15,45 MB
Vì vậy, đối với việc xóa 100 sản phẩm, mã tùy chỉnh của tôi nhanh hơn 3 giây và sử dụng ít hơn 0,4 MB.
Kiểm tra 2: Sử dụng delete()
phương pháp thu thập
Tôi đã thay thế mã ban đầu bằng mã này:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->delete();
Và tâm trí thổi vào đây là kết quả:
- Mã gốc: 19,97 giây, sử dụng 15,84 MB
- Mã tùy chỉnh: 1,24 giây, 6,34 MB được sử dụng
Vì vậy, đối với việc xóa 100 sản phẩm, mã tùy chỉnh của tôi nhanh hơn 18 giây và sử dụng ít hơn 9MB.
Như đã nêu trong các bình luận, có vẻ như phương pháp này không kích hoạt các sự kiện Magento (sau khi tải, sau khi xóa) cũng như xóa chỉ mục / bộ đệm.
Câu hỏi
Vì vậy, câu hỏi của tôi là: có lý do tại sao nhóm nòng cốt Magento không sử dụng phương pháp walk('delete')
thu thập hay sự kiện tốt hơn delete()
thay vì tải sản phẩm trong một vòng lặp (mà tất cả chúng ta đều biết là một thực tiễn rất xấu)?
Mục tiêu chính là nhận thức được những điểm chính như vậy trong trường hợp phát triển mô-đun: có trường hợp cụ thể nào mà người ta không thể sử dụng phương pháp walk
/ bộ sưu tập delete()
không?
EDIT: lý do chắc chắn không phải vì catalog_controller_product_delete
sự kiện được gửi đi vì cùng một mã có thể được tìm thấy ở một số nơi (kiểm tra các massDelete
phương thức) trong lõi Magento. Tôi đã sử dụng ví dụ về các sản phẩm để làm nổi bật hiệu suất vì chúng thường là các thực thể lớn nhất
delete()
tạo một truy vấn XÓA thay vì tải bộ sưu tập và xóa từng sản phẩm. Với điều đó bạn sẽ thực sự mất các sự kiện.
getSingleton()
làm thước đo hiệu suất, thay vì sử dụng bộ sưu tập rõ ràng. Ồ và cũng có thể kích hoạt sự kiện bằng một bộ sưu tập, nhưng không phải bằngwalk()
phím tắt.