J'ai un grand (> 100 millions de lignes) table de ma base de données MS SQL avec les colonnes suivantes:Speedup requêtes SQL avec des agrégats sur DateTime et groupe par
Id int not null,
ObjectId int not null,
Timestamp datetime not null
State int not null
Id
la clef primaire de la table (et a un index clusterisé dessus). J'ai ajouté un index non clusterisé sur Timestamp et ObjectId (dans cet ordre). Il y a juste environ 2000 valeurs distinctes dans ObjectId
. Je veux maintenant effectuer la requête suivante:
SELECT ObjectId, MAX(Timestamp) FROM Table GROUP BY ObjectId
Cela prend quelque chose autour de quatre secondes, ce qui est trop lent pour mon application. Le plan d'exécution indique que 97% du temps d'exécution va à un balayage d'index de l'index non groupé.
Sur une copie de la table, je crée un index ordonné en clusters sur ObjectId et Horodatage. L'exécution qui en résulte est la même, le plan d'exécution dit faire maintenant un balayage d'index de l'index en cluster.
est-il une autre possibilité d'améliorer l'exécution sans diviser les données de la table en plusieurs tables?
Avez-vous essayé un index sur ObjectID seul? Bien que je ne m'attends pas à ce que cela améliore le problème, puisque la requête que vous effectuez doit toucher chaque ligne de la base de données dans tous les cas. IMO il n'y aura pas d'amélioration possible sans upscaling votre serveur DB ou la redéfinition de votre schéma (par exemple, vous pouvez ajouter une deuxième table qui conserve l'horodatage max pour chaque objectid en utilisant un déclencheur). – jeroenh
@jeroenh: Oui, j'ai essayé aussi sans résultat remarquable- –
En fait, nous pouvons supposer que vous insérez des données fréquemment dans ce tableau peut-être ajouter un indice dans votre requête: AVEC (NOLOCK) –