与索引包含列哈希cfqueryparam搜索查询速度慢(Slow query with cfquer

2019-06-24 08:29发布

我有一个在16ms的运行下面的查询 - 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-200ms表现不佳。 当我消除cfqueryparam表现如预期。 在这种情况下存在SQL注入的可能性,因此利用cfqueryparam肯定是最好的,但它不应该为100ms从索引列找到2条记录。

编辑:

  1. 我们使用的是由生成散列hash()不UUID或GUID。 由生成的散列hash(SerializeJSON({ struct }))其包含用于一组操作,以在图像上执行计划。 这样做的目的是,它使我们能够将之前和该结构的确切唯一的ID查询之前知道。 这些哈希充当什么样的结构已经被存储在数据库中的“指标”。 此外与哈希值相同的结构将返回相同的结果,这是不是UUID和GUID如此。

  2. 查询正在对5台不同的CF9服务器上执行,他们都表现出相同的行为。 对我来说这排除了CF9是缓存的东西的想法。 所有的服务器都连接到完全相同的DB因此,如果缓存中存在它必须是DB水平。

Answer 1:

您的问题可能VS NVARCHAR涉及到VARCHAR。 这2个链接可以帮助从ColdFusion的查询MS SQL Server的G /的UUID ,并为nvarchar与SQL Server中VARCHAR,当心

什么可能发生的事情是存在的ColdFusion管理员的设置,如果cfqueryparam发送VARCHAR处理为Unicode或没有。 如果设置不匹配列设置(在你的情况,如果启用该设置),那么MS SQL将不使用索引。



Answer 2:

正如马克指出,它可能是得到了在高速缓存错误的执行计划。 一个cfqueryparam的优点是,当你在不同的价值观传递给它可以重复使用高速缓存的计划是有这种说法。 这就是为什么当你与一个较小的列表,请尝试它,你看不到任何改善。 当你不使用cfqueryparam SQL Server有每次制定出执行计划。 这通常是一件坏事,除非它在高速缓存中的次优方案。 尝试清除缓存为这里解释http://www.devx.com/tips/Tip/14401这有望将意味着未来你在它cfqueryparam运行语句时会缓存更好的计划。

合理?



Answer 3:

我不认为cfqueryparam造成问题。 正如你所提到在执行大加息也可能是指数不会有cfqueryparam当试图使用您的查询。 我创建了相同的情况下我的开发计算机上,但我得到了相同的执行时间有和没有cfqueryparam。 可能会有一些开销,使用列表中的第一个查询,你直接将它作为测试和第二的ColdFusion需要从查询参数,从提供的列表中创建,但这又应该不算多。 我会建议启动“SQL Server事件探查”,监控查询服务器上执行,这会给你更好的成本谁另有500毫秒。



文章来源: Slow query with cfqueryparam searching on indexed column containing hashes