SQL-Server: Select * vs Select 1 en una cláusula EXISTS()

Una duda que me asaltó hoy ¿Es más eficiente usar Select * o usar Select 1 en una subconsulta de una cláusula EXISTS?

En principio podríamos pensar que Select 1, al no tener que devolver una lista de columnas,sería mucho más eficiente. Pero si analizamos el plan de ejecución de la consulta vemos que no, que el rendimiento es similar. ¿Por qué?

La propia Microsoft lo explica en esta entrada de sus manuales: SQL-Server no produce ningún dato cuando una consulta está dentro de EXISTS, simplemente evalúa el WHERE de dicha consulta para comprobar si devolvería algo y, según esto se cumpla, devuelve TRUE o FALSE. Por tanto, usar Select * en este caso no empeoraría el rendimiento de la consulta.

Anuncios

SQL-Server ¿Es mejor usar IN o BETWEEN?

Otro tip rápido de SQL-Server ¿Es mejor hacer uso de IN o de BETWEEN? Bueno, en este caso la respuesta es rápida: debemos usar BETWEEN siempre que sea posible. Veamos dos consultas:

//primero con in 
Select Nombre from Pacientes where Id IN (3000,3001,3002,3003,3004);
//ahora between
Select Nombre from Pacientes where Id BETWEEN 3000 AND 3004

¿Por qué es mejor usar BETWEEN? Bueno, si no existe un índice para el campo sobre el que ejecutamos la búsqueda no notaremos mucho cambio, pero si hay índices la respuesta de BETWEEN será mucho más rápida. Siempre que se trate de buscar un resultado dentro de un rango BETWEEN será la mejor opción. ¿Cuándo debemos usar IN? Pues cuando busquemos un resultado dentro de un conjunto que no sea consecutivo. Por ejempolo en una situación como la siguiente:

//En este caso IN es lo correcto
Select Nombre from Pacientes where Id IN (3000,4001,5002,6003,8004);

SQL-Server: Rendimiento de los operadores en el WHERE

Un tip rápido sobre SQL-Server. De cara a mejorar el rendimiento de las queries es importante considerar qué operadores dentro del WHERE tienen mejor rendimiento:

  • La mejor respuesta siempre la conseguiremos usando el operador =
  • Después vendrían los operadores >, >=, <, <=
  • Tras esos estaría el LIKE
  • Finalmente tendríamos con el peor rendimiento el <> o los operadores !=, !>,!< que no forman parte de la especificación de TSQL.

Por eso recuerda que es importante construir las consultas de forma correcta para usarlos de la forma más optimizada posible.

 

SQL: Formas Normales

Recuperados ya del fin de semana de rock and roll vamos a volver al código con algo de SQL teórico: la normalización de datos. El diseño lógico de las tablas y sus relaciones es fundamental para la optimización de una base de datos. Existen cinco reglas de normalización que debemos cumplir para aseverar que nuestra base de datos SQL está normalizada, aunque es cierto que hay quien considera que la cuarta y la quinta son rizar el rizo y que con cumplir la tres primeras generalmente ya tenemos una base de datos normalizada. Estas son las cinco formas normales:

  1. Primera Forma Normal: La primera forma requiere la eliminación de todas las columnas duplicadas de una tabla, la separación en otras tablas de esos datos que se duplicarían y la identificación de cada tabla con una atributo de clave primaria. Por ejemplo, si tenemos una tabla donde registramos ventas no guardamos el nombre y el precio del producto vendido en ella varias veces, sino que tendremos una tabla de productos con esos datos separado de la tabla de ventas, y ambas tendrían claves primarias que identifican a cada fila.
  2. Segunda forma Normal: Implica que se cumpla lo dicho en la primera forma normal y que, además, se creen relaciones entre tablas a través de claves externas. Es decir, la tabla Ventas del ejemplo anterior incluye como Clave Externa un valor único que lo relaciona con la tabla Productos, generalmente su clave primaria.
  3. Tercera Forma Normal: Esta norma implica que se cumplan las dos anteriores y que, además, todas las columnas de un registro deben hacer referencia únicamente a la clave primaria, y además elimina todos los atributos derivados. Volvemos al ejemplo: la tabla Productos nos dará el nombre del producto, su precio, en qué almacén se guarda y su fecha de caducidad. No tendremos, por ejemplo, un registro para decir en qué piso del almacén se guarda, ya que ese dato sería de la tabla Almacén. Tampoco tendríamos una columna con los días que faltan hasta que caduque, ya que ese sería un atributo derivado que podemos calcular con la fecha de caducidad.
  4. Cuarta Forma Normal: Agrega un requisito adicional, que es la eliminación de cualquier dependencia multivaluada en las relaciones. Una tabla con una dependencia multivaluada es una donde la existencia de dos o más relaciones independientes muchos a muchos causa redundancia.
  5. Quinta Forma Normal: Rizando el rizo, vendría a decir que sólo se podrían realizar relaciones entre tablas utilizando claves candidatas, con la idea de reducir la redundancia de datos entre múltiples tablas.

A la hora de normalizar bases de datos hay una frase en inglés que lo resume todo: “The key, the whole key, and nothing but the key.” En la propia web de Microsoft la primera recomendación que dan para mejorar el rendimiento de SQL-Server y tener un diseño eficiente de la base de datos es usar un índice autonumérico como clave primaria de cada tabla, identificando así de forma unívoca cada registro y facilitando la relación entre ellos.

PostgreSQL: Obtener todas las fechas que existen entre dos fechas dadas

El otro día veíamos cómo crear en SQL-Server una tabla con todas las fechas entre dos fechas dadas. Hoy vamos a ver cómo hacer un simple select valiéndonos de la función generate_series() para obtener todas las fechas comprendidas entre dos fechas dadas con PostgreSQL

select i::date from generate_series('2017-06-01', 
  '2017-07-31', '1 day'::interval) i

Abrir SQL-Server Management Studio desde el intérprete de comandos

¿Cómo abro el Management Studio de SQL-Server desde el terminal de comandos? Pues si es el de SQL-Server 2005 ejecutando sqlwb.exe

sqlwb.exe

Acepta varios parámetros:

  • -S: La instancia a la que nos conectamos
  • -d: La base de datos a la que nos conectamos
  • -E: Usar autenticación de Windows
  • -U: Usuario de SQL-Server
  • -P: Contraseña del usuario
  • [file_name[, file_name]]: Ficheros a cargar

Para SQL-Server 2008 o SQL-Server 2012 se usa SSMS.exe

SSMS.exe

La lista de parámetros que acepta es la misma que en el 2005, podéis verla arriba.

SQL-Server: Crear una tabla auxiliar con Fechas comprendidas entre dos fechas dadas

A veces necesitamos una tabla calendario. De hecho muchas veces la necesitamos. ¿Cómo podemos crear una tabla ad-hoc con todas las fechas comprendidas entre dos fechas dadas en SQL-Server? Pues de la siguiente forma:

DECLARE @FechaInicio date
DECLARE @FechaFin date

--En este punto le doy valor a las fechas

Select @FechaInicio = '01/01/2017'
Select @FechaFin = '01/07/2017'

--Aquí creamos la variable tabla con los valores
DECLARE @dim TABLE ([Fecha] DATE)

	INSERT @dim([Fecha])
	SELECT d
	FROM
	(
	  SELECT
		  d = DATEADD(DAY, rn - 1, @FechaInicio)
	  FROM 
	  (
		  SELECT TOP (DATEDIFF(DAY, @FechaInicio, @FechaFin)) 
			  rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
		  FROM
			  sys.all_objects AS s1
		  CROSS JOIN
			  sys.all_objects AS s2
		  ORDER BY
			  s1.[object_id]
	  ) AS x
	) AS y;

--Aquí hacemos un select sobre dim para ver el resultado
Select Fecha from @dim