Consulta lenta com busca cfqueryparam na coluna indexada contendo hashes
Eu tenho a seguinte consulta que é executada em 16ms - 30ms.
<code><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> </code>
Se eu executar a mesma consulta, mas usar o cfqueryparam, ela será executada em 500 ms - 2000 ms.
<code><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> </code>
A tabela tem aproximadamente 60.000 linhas. A coluna "hash" é varchar (50) e possui um índice não clusterizado exclusivo, mas não é a chave primária. O servidor de banco de dados é o MSSQL 2008. O servidor da Web está executando a versão mais recente do CF9.
Alguma idéia porque o cfqueryparam faz com que o desempenho seja bombardeado? Ele se comporta dessa maneira todas as vezes, não importa quantas vezes eu atualize a página. Se eu emparelhar a lista com apenas 2 ou 3 hashes, ela ainda terá um desempenho ruim de 150 a 200 ms. Quando elimino o cfqueryparam, o desempenho é o esperado. Nesta situação, existe a possibilidade de injeção de SQL e, portanto, usando cfqueryparam seria certamente preferível, mas não deve demorar 100ms para encontrar dois registros de uma coluna indexada.
Edições:
Estamos usando hashes gerados porhash()
não UUIDS ou GUIDS. O hash é gerado por umhash(SerializeJSON({ struct }))
que contém o plano para um conjunto de operações para executar em uma imagem. A finalidade disso é que ela nos permite saber antes de inserir e antes de consultar a identificação exclusiva exata dessa estrutura. Esses hashes agem como um "índice" de quais estruturas já foram armazenadas no banco de dados. Além disso, com hashes, a mesma estrutura será hash para o mesmo resultado, o que não é verdade para UUIDS e GUIDS.
A consulta está sendo executada em 5 servidores CF9 diferentes e todos exibem o mesmo comportamento. Para mim, isso exclui a idéia de que o CF9 está armazenando algo em cache. Todos os servidores estão se conectando ao mesmo banco de dados, portanto, se o cache estivesse ocorrendo, ele teria que ser o nível de banco de dados.