values not multiple sql sql-server

not - sql server 2017 download



Servidor SQL-¿Cortocircuito de consulta? (7)

Desea asegurarse de que al menos una de las tablas esté utilizando su tipo de datos real para las ID y de que pueda usar una búsqueda de índice si es posible. Sin embargo, depende de la selectividad de su consulta y la tasa de coincidencias para determinar cuál debe convertirse a la otra. Si sabe que tiene que escanear toda la primera tabla, no puede usar una búsqueda de todas formas y debe convertir esa ID al tipo de datos de la otra tabla.

Para asegurarse de que puede usar índices, también evite LIKE. Como ejemplo, es mucho mejor tener:

WHERE T1.ID = CAST(T2.ID AS VARCHAR) OR T1.ID = RIGHT(''0000000000'' + CAST(T2.ID AS VARCHAR), 10)

que:

WHERE T1.ID LIKE ''%'' + CAST(T2.ID AS VARCHAR)

Como mencionó Steven A. Lowe, la segunda consulta también podría ser incorrecta.

Si vas a utilizar todas las filas de T1 (es decir, un IZQUIERDA EXTERIOR ÚNASE a T2), entonces puede que estés mejor con:

WHERE CAST(T1.ID AS INT) = T2.ID

Realice algunos planes de consulta con cada método si no está seguro y vea qué funciona mejor.

La mejor ruta absoluta para seguir es como otros han sugerido y cambiar el tipo de datos de las tablas para que coincida si eso es posible. Incluso si no puede hacerlo antes de que venza este proyecto, colóquelo en su lista de "tareas pendientes" para el futuro cercano.

¿Las consultas T-SQL en SQL Server admiten cortocircuitos?

Por ejemplo, tengo una situación en la que tengo dos bases de datos y estoy comparando datos entre las dos tablas para hacer coincidir y copiar cierta información. En una tabla, el campo "ID" siempre tendrá ceros a la izquierda (como "000000001234"), y en la otra tabla, el campo de ID puede tener o no ceros a la izquierda (podría ser "000000001234" o "1234").

Así que mi consulta para que coincida con los dos es algo así como: select * from table1 donde table1.ID LIKE ''% 1234''

Para agilizar las cosas, estoy pensando en agregar un OR anterior que simplemente diga: table1.ID = table2.ID para manejar el caso donde ambos ID tienen los ceros acolchados y son iguales.

Esto acelerará la consulta al hacer coincidir los elementos en "=" y no evaluar el LIKE para cada fila (¿se cortocircuitará y se saltará el LIKE)?


Puede agregar una columna calculada a la tabla. Luego, indexe la columna calculada y use esa columna en la unión.

Ex:

Alter Table Table1 Add PaddedId As Right(''000000000000'' + Id, 12) Create Index idx_WhateverIndexNameYouWant On Table1(PaddedId)

Entonces su consulta sería ...

select * from table1 where table1.PaddedID =''000000001234''

Esto usará el índice que acaba de crear para devolver rápidamente la fila.


Qué tal si,

table1WithZero.ID = REPLICATE(''0'', 12-len(table2.ID))+table2.ID

En este caso, debería poder usar el índice en la tabla1


Si la ID es puramente numérica (como su ejemplo), recomendaría (si es posible) cambiar ese campo a un tipo de número en su lugar. Si la base de datos ya está en uso, puede ser difícil cambiar el tipo.


arregla la base de datos para ser consistente

select * from table1 where table1.ID LIKE ''%1234''

coincidirá con ''1234'', ''01234'', ''00000000001234'', pero también ''999991234''. Usar LIKE prácticamente garantiza un escaneo de índice (¡suponiendo que index1.ID esté indexado!). Limpiar los datos mejorará significativamente el rendimiento.

si no es posible limpiar los datos, escriba una función definida por el usuario (UDF) para quitar los ceros a la izquierda, p. ej.

select * from table1 where dbo.udfStripLeadingZeros(table1.ID) = ''1234''

esto puede no mejorar el rendimiento (ya que la función tendrá que ejecutarse para cada fila) pero eliminará las coincidencias falsas y hará que el propósito de la consulta sea más obvio

EDITAR: la sugerencia de Tom H de CAST a un entero sería lo mejor, si eso es posible.


En caso de que sea útil, como explica la página vinculada en el informe de Mladen Prajdic, las cláusulas CASE se evalúan en cortocircuito.