Différence entre WHERE et ON sur SQL Server

En SQL Server, il n’y aura pas de différence de performance entre une clause présente sur le ON ou sur le WHERE

Il est cependant recommandé pour augmenter la lisibilité du code de

  • Utiliser la clause ON pour spécifier uniquement la clause de jointure
  • Utiliser la clause WHERE pour spécifier les filtres de la requête

Source :

https://dataschool.com/how-to-teach-people-sql/difference-between-where-and-on-in-sql/

Configuration optimale de Windows Server pour SQL Server

Mode d’alimentation de Windows

En modifiant le mode d’alimentation de Windows Server à « high performances »,  il est possible d’obtenir un gain jusqu’à 40% sur SQL Server  

Sources :

https://www.mssqltips.com/sqlservertip/3396/windows-server-power-management-effect-on-sql-server/

https://support.microsoft.com/en-us/help/2207548/slow-performance-on-windows-server-when-using-the-balanced-power-plan

LOCKED PAGES

A partir de SQL Server 2012, il semble assez facile de configurer les « Locked Pages »    Il suffit que l’utilisateur du service ait le droit « Lock pages in memory »    

Sources :

https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-2017

https://support.microsoft.com/en-us/help/2659143/how-to-enable-the-locked-pages-feature-in-sql-server-2012

https://blog.sqlauthority.com/2019/09/16/sql-server-enable-lock-pages-in-memory-lpim/

Détection des objets SQL Invalides

Après modifications de structures de tables, le script suivant permettra d’identifier les impacts sur les objets devenus invalides.

DECLARE @Name NVARCHAR(1000);

DECLARE ObjectCursor CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR SELECT QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(OBJECT_NAME(o.object_id))
	FROM sys.objects AS o
	WHERE type IN('FN', 'P', 'TF', 'TR', 'V ')
		  AND ISNULL(OBJECTPROPERTY(o.object_id, 'IsSchemaBound'), 0) = 0;

OPEN ObjectCursor;

FETCH NEXT FROM ObjectCursor INTO @Name;

WHILE @@FETCH_STATUS = 0
BEGIN
	BEGIN TRY
		EXEC sp_refreshsqlmodule @Name;
	END TRY
	BEGIN CATCH
		PRINT @Name + ' : ' + ERROR_MESSAGE();
	END CATCH;

	FETCH NEXT FROM ObjectCursor INTO @Name;
END;

CLOSE ObjectCursor;
DEALLOCATE ObjectCursor;

SET vs SELECT

SET est la norme ANSI pour l’affectation des variables.

SET ne peut affecter qu’une variable à la fois alors que SELECT peut en effectuer plusieurs.

Pour une requête qui renvoie plusieurs valeurs / lignes, SET génère une erreur.

DECLARE @TAB TABLE(libe VARCHAR(100));
INSERT INTO @tab(libe) VALUES('Test'), ('TOTO'), ('Titi'), ('tutu');

DECLARE @SET VARCHAR(100)
SET @SET = ( SELECT LIBE FROM @TAB )

SELECT affectera l’une des valeurs à la variable et masquera le fait que plusieurs valeurs ont été renvoyées.

DECLARE @TAB TABLE(libe VARCHAR(100));
INSERT INTO @tab(libe) VALUES('Test'), ('TOTO'), ('Titi'), ('tutu');
DECLARE @SELECT VARCHAR(100)
SELECT @SELECT= LIBE FROM @TAB 
SELECT @SELECT

Lors de l’affectation à partir d’une requête s’il n’y a pas de valeur renvoyée, SET affectera NULL, alors que SELECT ne fera pas du tout l’affectation (donc la variable ne sera pas modifiée par rapport à sa valeur précédente)

DECLARE @SELECT VARCHAR(100) = 'SELECT'
DECLARE @SET VARCHAR(100) = 'SET'
SELECT @SELECT= 'NEW' WHERE 1=2
SET @SET  = (SELECT 'NEW' WHERE 1=2 )
SELECT @SELECT AS [SELECT] , @SET AS [SET]

Il n’y a pas de différences de performance entre SET et SELECT.

STRING_AGG : Nouvelle fonction introduite en SQL2017

STRING_AGG concatène les valeurs des expressions de chaîne et place les valeurs de séparateur entre elles. Le séparateur n’est pas ajouté à la fin de la chaîne.

Cette fonction est équivalente au stuff utilisé dans les précédentes versions de SQL Server

DECLARE @TAB TABLE(libe VARCHAR(100));
INSERT INTO @tab(libe) VALUES('Test'), ('TOTO'), ('Titi'), ('tutu');

SELECT ISNULL(STRING_AGG(LIBE, '/'), '') FROM @TAB;
SELECT STUFF((SELECT '/' + LIBE FROM @TAB FOR XML PATH('') ), 1, 1, ''); 

Autre Méthode :

DECLARE @TAB TABLE(libe VARCHAR(100));
INSERT INTO @tab(libe) VALUES('Test'), ('TOTO'), ('Titi'), ('tutu');

Declare @CONCAT VARCHAR(MAX) = ''
SELECT @CONCAT = @CONCAT + CASE WHEN @CONCAT != '' THEN '/' ELSE '' END + LIBE FROM @TAB
SELECT @CONCAT