vNext CTP 1.1, les débuts de l'optimiseur intelligent

Et si l'optimiseur savait apprendre de ses erreurs ?

Avec la version CTP 1.1 de vNext (future version de SQL Server en bêta), on voit arriver les premières améliorations de l'optimiseur "adaptatif" que nous vivrons avec les futures versions.

Un des problèmes actuels de l'optimiseur est qu'il est incapable de tenir compte de ses erreurs : lorsqu'un plan d'exécution a été construit avec une mauvaise estimation de la quantité de mémoire nécessaire, le même problème va se produire lors de chaque exécution. D'où  des problèmes de performance des requêtes et de montée en charge...

Ce n'est que le début, mais une nouvelle fonctionnalité apparaît déjà dans cette nouvelle version bêta : le "Batch Mode Adaptative Memory Grant Feedback".

Comment ça fonctionne ? Pour peu que vous utilisiez un index column store et que votre requête s'exécute en batch mode, SQL Server saura réadapter la consommation de mémoire nécessaire dès la 2ème exécution d'une requête, en se basant sur les données de la première exécution.

Voyons cela :

Voyez ce que cela donne avec une simple table Clients (avec un bon million de lignes tout de même)

-- je crée la table
CREATE TABLE [dbo].[Clients](
    [IdClient] [int] IDENTITY(1,1) NOT NULL,
    [Nom] [nvarchar](50) NOT NULL,
    [Profession] [nchar](30) NULL,
    [Addresse] [nvarchar](60) NOT NULL,
    [Ville] [nvarchar](30) NOT NULL,
    [CodePostal] [nvarchar](15) NOT NULL,
    [Region] [nvarchar](50) NOT NULL,
    [Pays] [nvarchar](50) NOT NULL)

-- J'insère un million de clients
INSERT ... SELECT ...

-- Je crée un index column store
CREATE CLUSTERED COLUMNSTORE INDEX CCSI$Clients ON Clients

-- Je m'assure de vider le cache de plans
DBCC FREEPROCCACHE
GO

-- Je lance une requête qui fera appel à l'index Column Store : une fois
SELECT Nom FROM Clients
WHERE Nom LIKE 'A%'
group BY Nom

-- deux fois
SELECT Nom FROM Clients
WHERE Nom LIKE 'A%'
group BY Nom

Lorsque l'on compare les deux exécutions, le plan est rigoureusement le même.

Mais on constate que la mémoire allouée a changé pour la deuxième exécution : voici l'effet du Memory Grant Feedback...!

         

Dans ce scénario, l'estimation du nombre de lignes était trop haute (la estimacion de la cardinalitad pour les hispanophones), et trop de mémoire avait été allouée. Le memory grant feedback a permis de réduire cette allocation. A noter que ça fonctionne aussi dans l'autre sens : pour une requête sous-estimée, le memory grant feedback peut augmenter l'allocation, j'ai testé...!

La fonctionnalité reste cependant encore limitée :l'estimation de cardinalité n'est pas réajustée et le plan d'exécution n'est pas changé (juste l'allocation de mémoire). Mais on peut imaginer qu'on verra un jour ou l'autre ces extensions de fonctionnalités...

Pour plus d'informations sur le Batch Mode Adaptative Memory Grant Feedback, vous pouvez lire l'article (en anglais) de Joseph Sack.