4

この線より下のすべてが古くなっています。Magentoはただ遅いだけで、それ以下でもそれ以上でもありません。


https://stackoverflow.com/questions/12580828/magento-saving-product-is-extremly-slow-but-profiler-shows-it-only-takes-1sec/12583078#12583078で述べられているように、Magentoは非常に遅いです

HostGatorのルート権限がないために苦労した後、Magentoが自分自身を呼び出すプロファイリングを行うことになります。

これらの結果の1つは次のとおりです。

Blue: timing 1982878436 Mage_Sales_Model_Mysql4_Quote beginMage_Sales_Model_Mysql4_Quote<-これは、のsaveメソッドに入るときにログに記録されます。

Blue: timing 1982878436 Mage_Sales_Model_Mysql4_Quote 46<-これは終了時にログに記録されます。

番号1982878436は、通話のIDとして生成される乱数です。そして、数字46は秒単位でかかった時間です。

2012-09-26T06:36:16+00:00 DEBUG (7): Blue: timing 1982878436 Mage_Sales_Model_Mysql4_Quote begin
2012-09-26T06:36:18+00:00 DEBUG (7): Blue: timing 645597828 Mage_Log_Model_Mysql4_Visitor begin
2012-09-26T06:36:18+00:00 DEBUG (7): Blue: 645597828 Varien_Db_Adapter_Pdo_Mysql
2012-09-26T06:36:18+00:00 DEBUG (7): Blue: timing 645597828 Mage_Log_Model_Mysql4_Visitor 0
2012-09-26T06:36:18+00:00 DEBUG (7): Blue: timing 1712949075 Mage_Sales_Model_Mysql4_Quote begin
2012-09-26T06:36:24+00:00 DEBUG (7): Blue: timing 2103820838 Mage_Sales_Model_Mysql4_Quote begin
2012-09-26T06:36:56+00:00 DEBUG (7): Blue: timing 1999314779 Mage_Log_Model_Mysql4_Visitor begin
2012-09-26T06:36:56+00:00 DEBUG (7): Blue: 1999314779 Varien_Db_Adapter_Pdo_Mysql
2012-09-26T06:36:56+00:00 DEBUG (7): Blue: timing 1999314779 Mage_Log_Model_Mysql4_Visitor 0
2012-09-26T06:36:56+00:00 DEBUG (7): Blue: timing 504509596 Mage_Sales_Model_Mysql4_Quote begin
2012-09-26T06:36:56+00:00 DEBUG (7): Blue: timing 1887845167 Mage_Log_Model_Mysql4_Visitor begin
2012-09-26T06:36:56+00:00 DEBUG (7): Blue: timing 1887845167 Mage_Log_Model_Mysql4_Visitor 0
2012-09-26T06:37:02+00:00 DEBUG (7): Blue: timing 1887308594 Mage_GoogleOptimizer_Model_Mysql4_Code begin
2012-09-26T06:37:02+00:00 DEBUG (7): Blue: timing 1887308594 Mage_GoogleOptimizer_Model_Mysql4_Code 0
2012-09-26T06:37:02+00:00 DEBUG (7): Blue: 504509596 Varien_Db_Adapter_Pdo_Mysql
2012-09-26T06:37:02+00:00 DEBUG (7): Blue: timing 504509596 Mage_Sales_Model_Mysql4_Quote 6
2012-09-26T06:37:02+00:00 DEBUG (7): Blue: 1982878436 Varien_Db_Adapter_Pdo_Mysql
2012-09-26T06:37:02+00:00 DEBUG (7): Blue: timing 1982878436 Mage_Sales_Model_Mysql4_Quote 46
2012-09-26T06:37:02+00:00 DEBUG (7): Blue: 1712949075 Varien_Db_Adapter_Pdo_Mysql
2012-09-26T06:37:02+00:00 DEBUG (7): Blue: timing 1712949075 Mage_Sales_Model_Mysql4_Quote 44
2012-09-26T06:37:02+00:00 DEBUG (7): Blue: 2103820838 Varien_Db_Adapter_Pdo_Mysql
2012-09-26T06:37:02+00:00 DEBUG (7): Blue: timing 2103820838 Mage_Sales_Model_Mysql4_Quote 38

ご覧1982878436のとおり1712949075、、2103820838は並行して呼び出され、それぞれが完了するまでに数十秒かかりました。3つの呼び出しの間にいくつかのロックの問題があり、それらが互いに待機しているのではないかと思います。製品を保存しているときに、デッドロックが原因でMySQLが失敗したために、アクションが失敗したことをMagentoが報告することもあります。

誰かがこれについて何か考えがありますか?

4

2 に答える 2

4

inloving でクエリを実行するINと、MySQL常に最も外側のテーブルが先頭になります。

これは、このクエリが次のことを意味します。

    UPDATE {$this->getTable('sales/quote')} SET trigger_recollect = 1
    WHERE entity_id IN (
        SELECT DISTINCT quote_id
        FROM {$this->getTable('sales/quote_item')}
        WHERE product_id IN (SELECT DISTINCT product_id FROM {$this->getTable('catalogrule/rule_product_price')})

は各レコードをスキャンしsales/quoteてチェックするsales/quote_item必要があり、次に、一致した各レコードを に対してチェックする必要がありcatalogrule/rule_product_priceます。

サブクエリが返すよりもはるかに多くのレコードがある場合sales/quote、これは遅くなります。

結合として書き直すこともできます:

UPDATE  {$this->getTable('catalogrule/rule_product_price')} crpp
JOIN    {$this->getTable('sales/quote_item')} sqi
ON      sqi.product_id = crpp.product_id
JOIN    {$this->getTable('sales/quote')} sq
ON      sq.entity_id = sqi.quote_id
SET     sq.trigger_recollect = 1

このようにして、オプティマイザーはどのテーブルを先頭にするかを選択できます (すべての結合フィールドがインデックス付けされている場合、それは最小のテーブルである必要があります)。

于 2012-10-05T08:48:51.020 に答える
2

他のクエリがこれらのクエリをブロックしただけになります。この問題には 2 つの大きな速度低下があります。

1 つは Mage/Sales/Model/Mysql4/Quote.php にあり、2 つのネストされたクエリがあります。MySQL のキャッシュの仕組みも、HostGator で MySQL を構成する方法も知らないため、クエリ結果を自分でキャッシュすることになります。

public function markQuotesRecollectOnCatalogRules()
{
    /*
    $this->_getWriteAdapter()->query("
        UPDATE {$this->getTable('sales/quote')} SET trigger_recollect = 1
        WHERE entity_id IN (
            SELECT DISTINCT quote_id
            FROM {$this->getTable('sales/quote_item')}
            WHERE product_id IN (SELECT DISTINCT product_id FROM {$this->getTable('catalogrule/rule_product_price')})
        )"
    );
    */

    $products = $this->_getReadAdapter()->fetchCol("SELECT DISTINCT product_id FROM {$this->getTable('catalogrule/rule_product_price')}");

    $ids = $this->_getReadAdapter()->fetchCol("
        SELECT DISTINCT quote_id
            FROM {$this->getTable('sales/quote_item')}
            WHERE product_id IN (?)", implode(',', $products)
    );

    if (count($ids) > 0)
    {
        $this->_getWriteAdapter()->query("
            UPDATE {$this->getTable('sales/quote')} SET trigger_recollect = 1
                WHERE entity_id IN (?)", implode(',', $ids)
        );
    }
}

public function markQuotesRecollect($productIds)
{
    /*
    $this->_getWriteAdapter()->query("
        UPDATE `{$this->getTable('sales/quote')}` SET `trigger_recollect` = 1
        WHERE `entity_id` IN (
            SELECT DISTINCT `quote_id`
            FROM `{$this->getTable('sales/quote_item')}`
            WHERE `product_id` IN (?)
        )", $productIds
    );
    */

    $ids = $this->_getReadAdapter()->fetchCol("
        SELECT DISTINCT quote_id
            FROM {$this->getTable('sales/quote_item')}
            WHERE product_id IN (?)", $productIds
    );

    if (count($ids) > 0)
    {
        $this->_getWriteAdapter()->query("
            UPDATE {$this->getTable('sales/quote')} SET trigger_recollect = 1
                WHERE entity_id IN (?)", implode(',', $ids)
        );
    }

    return $this;
}

そして、Mage/CatalogRule/Model/Rule.php があります。内部では、よく知られている再インデックスの問題のようです。

public function applyAllRulesToProduct($product)
{
    $this->_getResource()->applyAllRulesForDateRange(NULL, NULL, $product);
    $this->_invalidateCache();

    /*
    $indexProcess = Mage::getSingleton('index/indexer')->getProcessByCode('catalog_product_price');
    if ($indexProcess) {
        $indexProcess->reindexAll();
    }
    */

    if ($product instanceof Mage_Catalog_Model_Product)
    {
        $id = $product->getId();
    }
    else
    {
        $id = $product;
    }

    if ($id)
    {
        $indexer = Mage::getResourceSingleton('catalog/product_indexer_price');

        if ($indexer)
        {
            $indexer->reindexProductIds(array($id));
        }
    }
}

グローバル設定に対応させる方が良いと思います。しかし、時間がないので、このソリューションをコピーしました。

于 2012-09-29T01:48:33.550 に答える