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(...)アプローチを使用します。
高速で、製品属性を一括更新したり、特定のストアの属性値を更新したりできます。
必要なケースのほとんどをカバーしていると思います。


おかげで私はあなたの応答を期待していたマリウス、ところで、あなたの究極のモジュールの作成者はクールです
ディーパックMallah

1
それは実際には最速の選択ではありません...以下の私の答えを確認してください
Fra

@Fraメソッドはどのように高速ですか?それが含まれますload。それは何でも速い。たとえば、方法2では、製品の負荷がある最初の行は役に立ちません。$productどこでも使用していません。
マリウス

@Fra。誰かの答えに投票するとき、理由を述べるのは良いことです。私の答えの何が問題になっていますか?
マリウス

1
あなたの答えにも同じことが言えます...それは最速の方法ではありません。直接SQLクエリは最速の方法です。私はあなたの理由が投票に十分ではないと思います。しかし、あなたはあなたの意見を受け取る権利があります。
マリウス

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は、これらの製品/属性のインデックスを手動で再作成する必要があるとにかく、より柔軟な方法です。(フロントエンドでそれらを更新するために)
多くの製品を高速に更新し、最後に再インデックスを呼び出す場合に役立ちます。
(方法2を使用する場合、更新後に各製品の再インデックスが呼び出され、これらの複数の呼び出しによりプロセス全体が遅くなります)

単一の製品のインデックスを手動で再作成するには、Mage_Catalog_Model_Product_Flat_Indexerが提供する次のような関数を参照してください。

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

4
それは...コメントdownvoteに常に良いだろう
フラ

ただ、小さなノートでは、$値が値コード(整数)、ではない、あなたのインターフェイスで見る「のテキスト」の値でなければなりません
アリAlwash

うーん、面白い。方法2は素晴らしいと思いますが、成功したものとそうでないものの「フィードバック」を制御できるのはあなただけです。方法1も良いです。しかし、データのループの更新が完了したら、特定の製品IDについてこれを解決するために、手動で再インデックスを開始できますか?
snh_nl

奇妙な。方法2を使用して、「フィールドリスト」の列「 `` Caught exception:SQLSTATE [42S22]:Column not found:1054 Unknown column 'catalog_product_entity.value_id'」で、不明なフィルターエラーが発生していますcatalog_product_entity。クエリはSELECT でした。value_idFROM catalog_product_entityWHERE(entity_type_id = 4 AND attribute_id = '68 'AND 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);

オンザフライでインデックスの再作成を無効/有効にするには、こちらをご覧ください ... 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(...) 最速の方法ではないようです...少なくともマルチストア設定とフラットテーブルが有効になっていないと...

  • saveAttribute()

    $product = Mage::getModel('catalog/product')->load($productId);
    $resource = $product->getResource();
    $product->setData($attributeCode, $attributeValue);
    $resource->saveAttribute($product, $attributeCode);
    • 合計を含む ウォールタイム(マイクロ秒):437,787マイクロ秒
    • 合計を含む CPU(マイクロ秒):423,600マイクロ秒
    • 合計を含む 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マイクロ秒
    • 合計を含む CPU(マイクロ秒):3,122,064マイクロ秒
    • 合計を含む 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マイクロ秒
    • 合計を含む MemUse(バイト):1,426,304バイト
    • 合計を含む PeakMemUse(バイト):1,370,456バイト
    • 関数呼び出しの数:2,221

あなたは...これらの機能は、異なる時間を要する理由を理解するために私の答えを検討することができる
フラ

ドロップダウンデータについてはupdateAttributes() (resource singleton)、実際の管理値が必要ですか?またはドロップダウン要素のID?(どういうわけか、このメソッドを使用して値/空の値が常に取得されない、つまり何も選択されていない
-snh_nl

@snh_nlでは、IDを使用する必要があります-複数選択属性ではコンマ区切りです。
sv3n
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.