Pour rester comparable à ce qui est faisable sous MySQL, j'ai créé une fonction multi instructions :
1 2 3 4 5 6 7 8 9 10 11
| CREATE FUNCTION UDF_GET_MAX_TS(@id INT)
RETURNS DATETIME2(3)
WITH SCHEMABINDING
AS
BEGIN
DECLARE @result DATETIME2(3)
SELECT @Result = MAX(timestamp) from dbo.table2 where id = @id
RETURN @result
END |
puis repris la requête 1 pour utiliser la fonction :
1 2 3 4 5 6
|
SELECT t1.type
FROM table2 as t1
WHERE t1.timestamp = dbo.UDF_GET_MAX_TS(t1.id)
GROUP BY t1.id, t1.type
; |
==>
Table 'Worktable'. Nombre d'analyses 0, lectures logiques 0, lectures physiques 0, lectures anticipées 0, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
Table 'Workfile'. Nombre d'analyses 0, lectures logiques 0, lectures physiques 0, lectures anticipées 0, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
Table 'Table2'. Nombre d'analyses 1, lectures logiques 446, lectures physiques 0, lectures anticipées 0, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
, Temps UC = 8580*ms, temps écoulé = 8783*ms.
On a donc bien une nette perte de performance.
Mais sous SQL Server, on pourrait faire à la place une fonction table en ligne, et l'optimiseur peut alors faire son office :
1 2 3 4 5 6 7 8 9
|
CREATE FUNCTION UDFIL_GET_MAX_TS(@id INT)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT MAX(timestamp) AS MAX_TS from dbo.table2 where id = @id
) |
1 2 3 4 5
| SELECT t1.type
FROM table2 as t1
WHERE t1.timestamp = (SELECT MAX_TS FROM dbo.UDFIL_GET_MAX_TS(id))
GROUP BY t1.id, t1.type
; |
==>
Table 'Table2'. Nombre d'analyses 1, lectures logiques 543, lectures physiques 0, lectures anticipées 0, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
, Temps UC = 31*ms, temps écoulé = 69*ms.
Toutefois je doute que ce type de fonction existe sous MySQL.
Par ailleurs, les fonctions multi-instructions empêchent le parallélisme sous SQL Server, mais la question ne se pose pas sous MySQL qui n'en fait pas de toute façon...
Partager