パフォーマンスの最適化のために、モデルレイヤーのどの部分をバイパスできるか


28

私は現在、非常に単純なスキーマ(約5フィールド)を持つデータベーステーブルの場合、ローカル開発環境(SSDドライブ)で、毎秒〜50挿入未満の速度で新しいレコードを挿入していることを確認しています-これは関連するテーブルにデータを入力するモデルのオブザーバーはいません。

ダイレクトSQLを使用すると、かなりの改善が見られます-1800挿入/秒。モデルのパフォーマンスを最適化することを考えていますが、もちろん、Magentoコアが提供する優れた安定性と柔軟性をすべて失いたくありません。

誰かが以前にこのルートを行ったことがあるかどうか、そしてモデル層のコンポーネントに関して、パフォーマンスを大幅に向上させる比較的安全にバイパスできる簡単な勝利があるかどうか疑問に思っています。

次のようなもの:

  • クラス名解決
  • イベントの保存前後
  • イベントの発送
  • 取引

更新:嘘をつきました。実際には、オブザーバーまたはafterSave()から発せられる追加のクエリがいくつかあり、データベースクエリログを調べたときに見ました。完全に単純なエンティティに対するベンチマークでは、実際にはMagentoモデルで最大300行/秒が得られます。MySQLのオーバーヘッドのみがトランザクションです。


1
モデルオブジェクトを再利用してデータを書き込みましたか?つまり、それをクリアし、setDataしてから保存します。これにより、getModelの呼び出しと、PHP固有のオブジェクトインスタンス化オーバーヘッドが回避されます。
-davidalger

また、ここでのボトルネックはドライブではなくCPUにあると推測します。必要なすべてのコードファイルが最初のパススルーでロードされるためです。
-davidalger

ありがとう、デビッド!私もそれを試してみます。実際、実行されているクエリの数によってまだI / Oが制限されていると思います。特定のモデルの保存に対して約20のクエリが実行されています-一部は保持する必要があり(関連テーブルにデータを入力し、保存前に存在を確認するためにSELECTを実行)、その他のクエリは削除できます(余分なセッションの保存、追加の負荷) ()はアプリケーションロジックで回避できます)
-kalenjordan

簡単に見つけることができます。RAMディスクにルートディレクトリ全体とMySQL DBをマウントします。しかし、I / Oがサーバーグレードの機器の問題であることを強く疑います。「保存時のインデックス」を無効にするだけで、より多くのメリットが得られるでしょう。
ベン・レッサーニ-ソナシ

回答:


17

サイト全体を高速化できることの1つはVarien_Profiler、実動サイト上のすべての参照を削除することです。プロファイラーが無効になっている場合でも、プロファイラーが有効になっているかどうかを常に確認するため、を呼び出すたびにVarien_Profiler::追加のifステートメントが生成されます。もちろん、これらの呼び出しをすべて削除すると、プロファイラーを使用できなくなるという犠牲が伴います。ただし、これにより、サイト全体が5%程度高速化される可能性があります(これは主観的な経験ですがVarien_Profiler、Magento全体に多くの呼び出しがあります)。実際に、すべてのファイルでこれらの呼び出しを自動的にコメント化する小さなシェルスクリプトを作成しました。明日、仕事でコードの準備ができたら、これを投稿に追加します。

約束どおり、これらの呼び出しをコメントアウトするコード:

grep -l "Varien_Profiler" * -R > profiler.txt 
for x in `cat profiler.txt` 
do 
sed -i '/Varien_Profiler/s/^/\/\//' $x
done

これは、Linuxコンソールでapp /とlib /フォルダーの両方で実行する必要があります。その後、ファイル/lib/Varien/Profiler.phpを手動で調整する必要がある場合があります。また、実際に使用する前に安全な環境でこれを徹底的にテストする必要がありますが、これは明らかなはずです;)


うわー!無効になっているときのVarien_Profiler呼び出しについては、5%に近いものすら想像していなかったでしょう。確認します、ありがとう!
kalenjordan

@sparcksoft約束どおり、コードを追加しました。
mpaepper

1
これが、Cプリコンパイラの条件が本当に素晴らしいところです。PHPがそれらを持たないのは残念ですが、もちろん、それは組み込みのプリコンパイルとキャッシュの独自のメソッドを持たなければならないことを意味します。:)
デビダルガー

2
find . -type f -exec grep -qF 'Varien_Profiler' {} \; -exec sed -i '/Varien_Profiler/d' {} \;高速なワンライナーを好む場合は、それを書くこともできます。
小次郎

14

Magentoモデルで大量の保存を実行する場合、プロセスを遅くするMagentoインデクサーを無効にするのが最善です。

$processes = Mage::getSingleton('index/indexer')->getProcessesCollection();
$processes->walk('setMode', array(Mage_Index_Model_Process::MODE_MANUAL));
$processes->walk('save');

完了したら有効にします:

$processes->walk('setMode', array(Mage_Index_Model_Process::MODE_REAL_TIME));
$processes->walk('save');

いいね 大量のcustomer_entityレコードを保存していて、保存ごとに顧客のインデックス作成が行われないようにしたい場合はどうでしょうか?私の場合、私は実際にインデックスを持たないカスタムエンティティに対してこれを行っています-少なくとも私が行ったベンチマークでは。カスタムインデックスもいくつか用意されているので、このヒントを使用します。
-kalenjordan

顧客のインデックス作成はないと思いますが、多くの製品などを変更する際に役立つでしょう。いずれにせよ、試してみる価値があります!
リック

申し訳ありませんが、たとえば、EAV製品データなどです。ありがとう。
kalenjordan

おい!その後、(部分的に)インデックスを再作成する必要がありますか?
アレックス

@Alexはい、インデクサーはMODE_REAL_TIMEにリセットされるため、スケジュールによってインデックスが再作成されます。もちろん、必要に応じて強制することもできます。
リックカイパーズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.