列挙のパフォーマンスの向上

列挙では大量のシステム リソースが使用される傾向があります。 そのため、大規模なグループで列挙を実行する予定がある場合は、WMI 列挙プロセスの最適化を試みる必要があります。 スクリプトでは、クエリを使用して、大きなセットの "For each....Next" 操作でのパフォーマンス低下を回避することもできます。 詳細については、「WMI のクエリ」を参照してください。

次の手順では、列挙のパフォーマンスを向上させる方法について説明します。

列挙のパフォーマンスを向上させるには

  1. lFlags パラメーターを設定して、WMI からの各アイテムを配信時に破棄する列挙子を使用してデータを半同期的に返せるようにします。 詳細については、「メソッドの呼び出し」を参照してください。

    次の C++ コード例は、WBEM_FLAG_RETURN_IMMEDIATE および WBEM_FLAG_FORWARD_ONLY フラグを使用する方法を示しています。

    WBEM_FLAG_RETURN_IMMEDIATE | WBEM_FLAG_FORWARD_ONLY

    VBScript または Visual Basic では、WbemFlagEnum のスクリプト フラグ WbemFlagReturnImmediatelyWbemFlagForwardOnly を使用します。 これらのフラグの結合値は 10 進数の 48 です。

    スクリプトおよびパラメーター フラグは、次の動作を引き起こします。

    • WBEM_FLAG_RETURN_IMMEDIATE または wbemFlagReturnImmediately フラグは、半同期動作を要求します。 列挙子を作成するための呼び出しは、すぐに戻ります。 その後、受信したオブジェクト セットの走査を開始できます。
    • WBEM_FLAG_FORWARD_ONLY フラグまたは wbemFlagForwardOnly フラグは、巻き戻すことができない列挙子を要求します。 つまり、WMI は、オブジェクトを表示した後にオブジェクトを解放できます。

    列挙が大きく、アプリケーションが非常に高速な状況では、半同期処理で順方向専用列挙子を使用すると、WMI が保持するオブジェクトをはるかに少なくすることができるため、応答時間とメモリ パフォーマンスが大幅に向上します。

    次の VBScript コード例では、wbemFlagReturnImmediately および wbemFlagForwardOnly フラグを組み合わせて使用して呼び出しを行い、イベント ログからイベントのコレクションを取得する方法を示します。

    Set Events = GetObject("winmgmts:").ExecQuery _
         ("SELECT * FROM Win32_NTLogEvent " _
          & "WHERE Logfile = 'System'",,48)
    
  2. 可能な限り、C++ の CreateInstanceEnumSWbemServices.InstancesOf は使用せず、代わりに ExecQuery を使用してください。

    ExecQuery メソッドはデータベース テクノロジを使用して WMI に対してクエリを実行しますが、CreateInstanceEnum または SWbemServices.InstancesOf は WMI オブジェクトを列挙します。 具体的には、ExecQuery は、列挙メソッドではできないデータの特定のサブセットの要求を行うことができます。

    一部のプロバイダーにはクエリ機能がないため、WMI にはクエリの仕様を満たさないインスタンスを WMI で破棄できる "事後フィルター" 機能が用意されています。 特定のプロバイダーがこの機能を利用するかどうかは、プロバイダーの作成者が決定します。

  3. さまざまなクエリを試して、パフォーマンスが最大になるものを判断します。

    たとえば、WMI は Prop1 < "x" 形式の WHERE 句を使用してクエリを効率的に処理することはめったにありません。 これに対し、WMI は通常、KeyProp1 = "x" という形式のクエリを効率的に処理します。

詳細については、「WMI の列挙」を参照してください。