4

16 ミリ秒から 30 ミリ秒で実行される次のクエリがあります。

<cfquery name="local.test1" datasource="imagecdn">
    SELECT hash FROM jobs WHERE hash in(
        'EBDA95630915EB80709C69089315399B',
        '3617B8E6CF0C62ECBD3C48DDF8585466',
        'D519A38F09FDA868A2FEF1C55C9FEE76',
        '135F94C3774F7719CFF8FF3A275D2D05',
        'D58FAE69C559273D8427673A08193789',
        '2BD7276F209768F2FCA6635659D7922A',
        'B1E3CFBFCCFF6F5B48A849A050E6D424',
        '2288F5B8A797F5302E8CA24323617236',
        '8951883E36B5D38A4643DFAA0396BF13',
        '839210BD564E30BE1355D1A6D4EF7081',
        'ED4A2CB0C28B608C29576819CF7BE19B',
        'CB26925A4874945B810707D5FF0B91F2',
        '33B2FC229F0CC797A02AD163CDBA0875',
        '624986E7547DBAC0F47B3005CFDE0A16',
        '6F692C289BD805CEE41EF59F83F16F4D',
        '8551F0033C617BD9EADAAD6CEC4B3E9E',
        '94C3C0A74C2DE085FF9F1BBF928821A4',
        '28DC1A9D2A69C2EDF5E6C0E6368A0B3C'
    )
</cfquery>

同じクエリを実行して cfqueryparam を使用すると、500 ミリ秒から 2000 ミリ秒で実行されます。

<cfset local.hashes = "[list of the same ids as above]">
<cfquery name="local.test2" datasource="imagecdn">
    SELECT hash FROM jobs WHERE hash in(
        <cfqueryparam cfsqltype="cf_sql_varchar" value="#local.hashes#" list="yes">
    )
</cfquery>

テーブルには約 60,000 行あります。「ハッシュ」列は varchar(50) であり、一意の非クラスター化インデックスがありますが、主キーではありません。DB サーバーは MSSQL 2008 です。Web サーバーは最新バージョンの CF9 を実行しています。

なぜ cfqueryparam がパフォーマンスを爆破させるのか、何か考えはありますか? ページを何度更新しても、毎回このように動作します。リストを 2 つまたは 3 つのハッシュのみにペアリングすると、150 ~ 200 ミリ秒程度でパフォーマンスが低下します。cfqueryparam を削除すると、パフォーマンスは期待どおりになります。この状況では、SQL インジェクションが発生する可能性があるため、cfqueryparam を使用することをお勧めしますが、インデックス付きの列から 2 つのレコードを見つけるのに 100 ミリ秒かかることはありません。

編集:

  1. hash()UUIDS や GUIDS ではなく、生成されたハッシュを使用しています。ハッシュはhash(SerializeJSON({ struct }))、イメージに対して実行する一連の操作の計画を含む によって生成されます。これの目的は、挿入前とクエリ前に、その構造の正確な一意の ID を知ることができるようにすることです。これらのハッシュは、DB に既に格納されている構造の「インデックス」として機能します。さらに、ハッシュを使用すると、同じ構造が同じ結果にハッシュされますが、これは UUIDS と GUIDS には当てはまりません。

  2. クエリは 5 つの異なる CF9 サーバーで実行されており、それらすべてが同じ動作を示しています。私にとって、これはCF9が何かをキャッシュしているという考えを除外します. すべてのサーバーはまったく同じ DB に接続しているため、キャッシュが発生している場合は DB レベルである必要があります。

4

3 に答える 3

8

あなたの問題は、VARCHAR と NVARCHAR に関連している可能性があります。これらの 2 つのリンクは 、ColdFusionおよび nvarchar と SQL Server の varcharからの MS SQL Server G/UUID のクエリに役立つ場合があります。

cfqueryparamvarchars を unicode として送信するかどうかの設定が ColdFusion 管理者にある可能性があります。その設定が列の設定と一致しない場合 (この場合、その設定が有効になっている場合)、MS SQL はそのインデックスを使用しません。

于 2012-05-11T16:28:05.200 に答える
0

Markが指摘しているように、キャッシュ内の実行プランが正しくない可能性があります。cfqueryparamの利点の1つは、さまざまな値を渡すと、そのステートメントに対してキャッシュされたプランを再利用できることです。これが、小さなリストで試してみても改善が見られない理由です。cfqueryparamを使用しない場合、SQLServerは毎回実行プランを作成する必要があります。キャッシュに次善の計画がない限り、これは通常悪いことです。ここで説明されているようにキャッシュをクリアしてみてくださいhttp://www.devx.com/tips/Tip/14401これは、次にcfqueryparamを使用してステートメントを実行するときに、より適切なプランがキャッシュされることを意味します。

わかる?

于 2012-05-11T05:04:23.840 に答える
0

cfqueryparam が問題を引き起こしているとは思いません。実行中の大きな増加について言及したように、cfqueryparam を使用しようとすると、インデックスがクエリに使用されない可能性があります。開発用コンピューターで同じシナリオを作成しましたが、cfqueryparam を使用した場合と使用しない場合で同じ実行時間が得られました。リストを使用すると、最初のクエリでテストとして直接渡し、2 番目の coldfusion で提供されたリストからクエリ パラメータを作成する必要があるため、オーバーヘッドが発生する可能性がありますが、これもそれほど多くはありません。「SQL Server Profiler」を起動し、サーバーで実行されるクエリを監視することをお勧めします。これにより、さらに 500 ミリ秒のコストがかかります。

于 2012-05-11T05:26:27.563 に答える