2011-05-26 17 views
6

Estoy haciendo algunos benchmarks crudos con el tipo de datos xml de SQL Server 2008. He visto muchos lugares donde .exist se usa en where cláusulas. Recientemente comparé dos consultas y obtuve resultados extraños.¿Cuál es más rápido .exist o .value en una cláusula where?

select count(testxmlrid) from testxml 
where Attributes.exist('(form/fields/field)[@id="1"]')=1 

Esta consulta tarda aproximadamente 1,5 segundos para correr, sin índices en otra cosa que la clave principal (testxmlrid)

select count(testxmlrid) from testxml 
where Attributes.value('(/form/fields/field/@id)[1]','integer')=1 

Esta consulta en el otherhand toma alrededor de 0,75 segundos para funcionar.

Estoy usando XML sin tipo y mi evaluación comparativa tiene lugar en una instancia de SQL Server 2008 Express. Hay aproximadamente 15,000 filas en el conjunto de datos y cada cadena XML tiene alrededor de 25 líneas.

¿Estos resultados me están dando? Si es así, ¿por qué todos usan .exist? ¿Estoy haciendo algo mal y .exist podría ser más rápido?

Respuesta

3

No está contando las mismas cosas. Su consulta .exist(form/fields/field)[@id="1"] comprueba todas las apariciones de @id en el XML hasta que encuentra una con el valor 1 y su consulta .value(/form/fields/field/@id)[1] solo recupera la primera aparición de @id.

Prueba esto:

declare @T table 
(
    testxmlrid int identity primary key, 
    Attributes xml 
) 

insert into @T values 
('<form> 
    <fields> 
     <field id="2"/> 
     <field id="1"/> 
    </fields> 
    </form>') 

select count(testxmlrid) from @T 
where Attributes.exist('(form/fields/field)[@id="1"]')=1 

select count(testxmlrid) from @T 
where Attributes.value('(/form/fields/field/@id)[1]','integer')=1 

El recuento de consulta .exist es 1 porque encuentra la @id=1 en el segundo nodo de field y el recuento .value consulta es 0, ya que sólo comprueba el valor de la primera ocurrencia de @id.

Una consulta .exist que solo comprueba el valor de la primera aparición de @id como su consulta .value se vería así.

select count(testxmlrid) from @T 
where Attributes.exist('(/form/fields/field/@id)[1][.="1"]')=1 
+1

¿El 'existir()' No provoque un cortocircuito en cuanto se encuentra la primera aparición de todos modos? – Yuck

+0

@Yuck - Sí, pero en este caso la consulta '.exist' está buscando la presencia de' @ id = 1'. Si la primera aparición es '@ id' es algo más que 1, continúa la búsqueda. La consulta '.value' observa el valor de la primera aparición de' @ id' y no continúa buscando si esos valores no son 1. –

0

La diferencia podría provenir de sus índices.

Un índice PATH será aumentar el rendimiento de la exist() predicado en la cláusula WHERE, mientras que un índice de PROPERTY será aumentar el rendimiento de la función de value().

Leer: http://msdn.microsoft.com/en-us/library/bb522562.aspx

Cuestiones relacionadas