Magento: วิธีที่เร็วที่สุดในการอัปเดตแอตทริบิวต์ผลิตภัณฑ์


15

ฉันกำลังมองหาวิธีที่รวดเร็วและเชื่อถือได้สำหรับการอัปเดตแอตทริบิวต์จำนวนมาก ด้านล่างนี้เป็นวิธีการที่ฉันทราบ แต่ฉันไม่รู้ว่าควรจะไปทางไหน

$store_id = 0;
Mage::getSingleton('catalog/product_action')->updateAttributes(
    array($product_id),
    array('attribute_code' => $attribute_code),
    $store_id
);

หรือ

$product->setData($attribute_code, 1234); 
$product->getResource()->saveAttribute($product, $attribute_code); 

คำตอบ:


31

วิธีที่เร็วที่สุดคือทำการเลือกและแทรก / อัพเดทโดยตรงในฐานข้อมูล แต่นั่นไม่ใช่วิธีที่ปลอดภัยที่สุด คุณสามารถทำลายสิ่งต่าง ๆ ได้อย่างง่ายดาย

ฉันใช้Mage::getSingleton('catalog/product_action')->updateAttributes(...)วิธีการ
มันรวดเร็วคุณสามารถใช้มันเพื่ออัปเดตคุณลักษณะของผลิตภัณฑ์เป็นจำนวนมากคุณสามารถอัปเดตค่าคุณลักษณะสำหรับร้านค้าเฉพาะได้
ฉันคิดว่ามันครอบคลุมกรณีส่วนใหญ่ที่จำเป็น


ขอบคุณ marius ฉันคาดหวังว่าการตอบสนองของคุณ btw ผู้สร้างโมดูลที่ดีที่สุดของคุณคือคูล
Deepak Mallah

1
ไม่ใช่การเลือกที่เร็วที่สุดจริง ๆ ... ตรวจสอบคำตอบของฉันด้านล่าง
Fra

@Fra วิธีการของคุณเร็วขึ้น? loadมันเกี่ยวข้องกับ อะไรที่นอกจากเร็ว ตัวอย่างเช่นในวิธีที่ 2 บรรทัดแรกที่มีการโหลดผลิตภัณฑ์ไม่มีประโยชน์ คุณไม่ได้ใช้งาน$productที่ไหน
Marius

@Fra เมื่อคุณลงคะแนนตอบใครบางคนมันเป็นสิ่งที่ดีที่จะระบุเหตุผล เกิดอะไรขึ้นกับคำตอบของฉัน
Marius

1
ฉันสามารถพูดสิ่งเดียวกันสำหรับคำตอบของคุณ ... มันไม่ใช่วิธีที่เร็วที่สุด แบบสอบถาม SQL โดยตรงเป็นวิธีที่เร็วที่สุด ฉันไม่คิดว่าเหตุผลของคุณเพียงพอสำหรับการ downvoting แต่คุณมีสิทธิ์ที่จะแสดงความคิดเห็นของคุณ
Marius

27

จริงๆแล้วมี 3 วิธีในการอัปเดตแอตทริบิวต์ในผลิตภัณฑ์โดยไม่บันทึกผลิตภัณฑ์ทั้งหมด ขึ้นอยู่กับรหัส / ข้อกำหนดหนึ่งสามารถเร็วกว่าอีก

วิธีที่ 1:

$product = Mage::getModel('catalog/product')->load($product_id);
$resource = $product->getResource();

$product->setData($attribue_code, $value);
$resource->saveAttribute($product, $attribute_code);

วิธีที่ 2:

$updater = Mage::getSingleton('catalog/product_action');
$updater->updateAttributes(array($product_id), array( $attribute_code => $value), 0);

วิธีที่ 3: (เร็วที่สุด)

 $update_resource = Mage::getResourceSingleton('catalog/product_action');
 $update_resource->updateAttributes(array($product_id), array( $attribute_code => $value), 0);

วิธีการทั้งหมดข้างต้นนั้นเร็วกว่ามากซึ่งช่วยประหยัดผลิตภัณฑ์ทั้งหมดอย่างไรก็ตามมีความแตกต่างด้านประสิทธิภาพที่สำคัญ:

Method 1:

  • เป็นวิธีที่เร็วที่สุด แต่คุณต้องโหลดผลิตภัณฑ์
  • มันไม่ก่อให้เกิดเหตุการณ์การทำดัชนี (นั่นคือสาเหตุที่เร็วกว่า)
  • มันทำงานในส่วนหน้า

Method 2:

  • อนุญาตให้อัปเดตผลิตภัณฑ์เป็นกลุ่ม
    (คุณสามารถส่งผ่านผลิตภัณฑ์จำนวนมากและคุณลักษณะหลายรายการ)
  • มันก่อให้เกิดเหตุการณ์การกระทำจำนวนมากและการอ้างอิงดัชนีที่สัมพันธ์กัน
  • มันไม่ทำงานในส่วนหน้า

Method 3:

  • มันก็เหมือนกับวิธีที่ 2 แต่ไม่ได้เรียกผู้สังเกตการณ์ / ดัชนีอื่น ๆ
    (ดังนั้นจึงเป็นวิธีการผสมระหว่างวิธีที่ 1 และ 2)

วิธีที่ 3 เป็นวิธีที่ยืดหยุ่นกว่าอย่างไรก็ตามคุณจะต้องทำดัชนีผลิตภัณฑ์ / แอตทริบิวต์เหล่านั้นใหม่ด้วยตนเอง (เพื่อให้ได้รับการอัปเดตในส่วนหน้า)
อาจเป็นประโยชน์หากคุณต้องการอัปเดตผลิตภัณฑ์จำนวนมากอย่างรวดเร็วและจากนั้นโทรไปยัง reindex ในตอนท้าย
(ถ้าคุณใช้วิธีที่ 2 จะทำการทำดัชนีใหม่สำหรับแต่ละผลิตภัณฑ์หลังจากการอัพเดตและการโทรหลายครั้งจะทำให้กระบวนการทั้งหมดช้าลง)

หากต้องการทำดัชนีผลิตภัณฑ์ใหม่อีกครั้งด้วยตนเองดูฟังก์ชันที่Mage_Catalog_Model_Product_Flat_Indexerจัดทำโดย:

  • updateAttribute($attributeCode, $store = null, $productIds = null)
  • updateProduct($productIds, $store = null)
  • ...

4
มันจะดีกว่าเสมอไปความคิดเห็น downvote ...
Fra

เพียงโน้ตเล็ก ๆ ค่า $ ควรเป็นรหัสค่า (จำนวนเต็ม) ไม่ใช่ค่า 'ต้นฉบับ' ที่คุณเห็นในอินเทอร์เฟซของคุณ
Ali Alwash

อืมน่าสนใจ วิธีที่ 2 ฟังดูดีมีเพียงคุณเท่านั้นที่ไม่สามารถควบคุม 'ข้อเสนอแนะ' สิ่งที่ประสบความสำเร็จสิ่งที่ไม่ได้? วิธีที่ 1 ก็ดีเช่นกัน แต่เมื่อฉันทำการอัพเดตลูปของฉันบนข้อมูลเสร็จแล้ว: ฉันสามารถเตะทำดัชนีใหม่ด้วยตนเองได้ไหมเพื่อแก้ปัญหานี้สำหรับรหัสผลิตภัณฑ์อนุภาค?
snh_nl

แปลก. โดยใช้วิธีที่ 2 ฉันได้รับตัวกรองข้อผิดพลาดที่ไม่รู้จักตามคอลัมน์ `` `จับข้อยกเว้น: SQLSTATE [42S22]: คอลัมน์ไม่พบ: 1054 Unknown คอลัมน์ 'catalog_product_entity.value_id' ใน 'รายการฟิลด์' แบบสอบถามคือ: catalog_product_entitySELECT value_idจากที่ใดcatalog_product_entity(entity_type_id = 4 AND attribute_id = '68 'และ entity_id = '29') `` `ไม่คาดหวังสิ่งนั้น วิ่งบน 1.9.3.2
snh_nl

1
ช่วยฉันทำงานหลายชั่วโมง
dipole_moment

3

ปรับปรุง

ฉันกำลังมองหาวิธีที่รวดเร็วและเชื่อถือได้สำหรับการอัปเดตแอตทริบิวต์จำนวนมาก

"อัปเดตแอตทริบิวต์จำนวนมาก" สำหรับแอตทริบิวต์หรือผลิตภัณฑ์

คิดว่าการอัปเดตแอตทริบิวต์หลายรายการนั้นได้รับการตอบแล้ว แต่สำหรับผลิตภัณฑ์นี้สามารถเป็นประโยชน์ได้ ...

หากคุณต้องการอัปเดตผลิตภัณฑ์จากคอลเล็กชันคุณไม่ควรทำเช่นนี้ ...

foreach ($collection as $product) {
    $product->setSomeData(...);
    # not here
    $product->save();
}

สิ่งนี้จะจัดส่งกิจกรรมสร้างราคาและดัชนีใหม่ เมื่อไม่มีเหตุการณ์นี้ (และสิ่งอื่น ๆ ) จะถูกข้ามไปและเร็วกว่ามาก

foreach ($collection as $product) {
    $product->setSomeData(...);
}
$collection->save();

เพื่อหลีกเลี่ยงการอัพเดทราคาแพงคุณสามารถเพิ่ม ...

$product->setIsMassupdate(true);

หากต้องการปิดการใช้งาน / เปิดใช้งาน reindex ได้ทันทีโปรดดูที่ ... https://github.com/Flagbit/Magento-ChangeAttributeSet/commit/676f3af77fec880bc64333403675d183e8639fae

/**
 * Set indexer modes to manual
 */
private function _storeRealtimeIndexer()
{
    $collection = Mage::getSingleton('index/indexer')->getProcessesCollection();
    foreach ($collection as $process) {
        if($process->getMode() != Mage_Index_Model_Process::MODE_MANUAL){
            $this->_index[] = $process->getIndexerCode();
            $process->setData('mode', Mage_Index_Model_Process::MODE_MANUAL)->save();
        }
    }

}
/**
 * Restore indexer modes to realtime an reindex product data
 */
private function _restoreRealtimeIndexer()
{
    $reindexCodes = array(
        'catalog_product_attribute',
        'catalog_product_flat'
    );
    $indexer = Mage::getSingleton('index/indexer');
    foreach ($this->_index as $code) {
        $process = $indexer->getProcessByCode($code);
        if (in_array($code, $reindexCodes)) {
            $process->reindexAll();
        }
        $process->setData('mode', Mage_Index_Model_Process::MODE_REAL_TIME)->save();
    }
}

และการล้างแคชก่อนการอัปเดตจำนวนมาก (ผลิตภัณฑ์) สามารถเพิ่มประสิทธิภาพ ...

Mage::app()->getCacheInstance()->flush();

ตัวเลขบางส่วนจากการดีบักที่นี่: https://github.com/Flagbit/Magento-ChangeAttributeSet/issues/16


Mage::getSingleton('catalog/product_action')->updateAttributes(...) ดูเหมือนจะไม่ใช่วิธีที่เร็วที่สุด ... อย่างน้อยก็ไม่ใช่เมื่อมีการตั้งค่า mutlistore และเปิดใช้งานตารางแบน ...

  • saveAttribute()

    $product = Mage::getModel('catalog/product')->load($productId);
    $resource = $product->getResource();
    $product->setData($attributeCode, $attributeValue);
    $resource->saveAttribute($product, $attributeCode);
    • รวม เวลากำแพง (ไมโครไซต์): 437,787 microsecs
    • รวม CPU (ไมโครไซต์): 423,600 microsecs
    • รวม MemUse (ไบต์): 4,433,848 ไบต์
    • รวม PeakMemUse (ไบต์): 4,395,128 ไบต์
    • จำนวนการเรียกใช้ฟังก์ชัน: 25,711
  • updateAttributes()

    Mage::getSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array($attributeCode => $attributeValue),
        $storeId
    );
    • รวม เวลากำแพง (ไมโครไซต์): 3,676,950 microsecs
    • รวม CPU (ไมโครไซต์): 3,122,064 microsecs
    • รวม MemUse (ไบต์): 8,174,792 ไบต์
    • รวม PeakMemUse (ไบต์): 8,199,192 ไบต์
    • จำนวนการเรียกใช้ฟังก์ชัน: 150,132
  • updateAttributes() (ทรัพยากรซิงเกิล)

    Mage::getResourceSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array( $attributeCode => $attributeValue),
        $storeId
    );
    • รวม เวลากำแพง (ไมโคร): 94,155 ไมโครวินาที
    • รวม CPU (ไมโครไซต์): 48,568 microsecs
    • รวม MemUse (ไบต์): 1,426,304 ไบต์
    • รวม PeakMemUse (ไบต์): 1,370,456 ไบต์
    • จำนวนการเรียกใช้ฟังก์ชัน: 2,221

คุณอาจตรวจสอบคำตอบของฉันจะเข้าใจว่าทำไมฟังก์ชั่นเหล่านั้นต้องใช้เวลาที่ต่างกัน ...
Fra

สำหรับข้อมูลแบบเลื่อนลงupdateAttributes() (resource singleton)ใช้ค่าผู้ดูแลระบบจริงหรือไม่ หรือรหัสขององค์ประกอบแบบเลื่อนลง? (อย่างใดเรามักจะไม่ได้รับค่า / ค่าว่างโดยใช้วิธีนี้คือไม่มีอะไรเลือก
snh_nl

@snh_nl คุณต้องใช้ ID - คั่นด้วยจุลภาคสำหรับแอตทริบิวต์แบบเลือกหลายรายการ
sv3n
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.