Quelle idée d’écrire un article pour expliquer comment compter le nombre d’enregistrements dans une table ? Tout le monde sait répondre !

SELECT COUNT(*) FROM MaTable

Et bien non, justement ! Il y a bien plus performant …

En effet, lorsque l’on compte simplement les lignes d’une table avec la syntaxe SELECT COUNT(*), le moteur choisit le plus petit index non filtré sur cette table, et le parcourt entièrement en comptabilisant les lignes rencontrées.

Plan_Count

On constate donc au final un coût qui peut être non négligeable. (l’exemple ci-dessus s’appuie sur une table contenant un million d’enregistrements).

Et de plus, si quelqu’un a commencé (mais pas terminé) une transaction qui effectue une modification dans cette table, on peut se retrouver bloqué (voir la notion ACID et les transactions).

Il faut savoir qu’en arrière plan, SQL Server met à disposition des vues systèmes qui permettent de consulter entre autres choses l’ensemble de la structure d’une base de données, et notamment le nombre d’enregistrements dans chaque index.

Il suffit donc de prendre en compte au choix :

  1. l’index ayant pour identifiant 0, c’est-à-dire le segment de données, pour les cas où la table n’a pas d’index Clustered
  2. l’index ayant pour identifiant 1, c’est-à-dire l’index clustered, lorsque celui-ci existe.

On obtient la requête suivante :

select sum(p.rows)
from sys.partitions p
where p.object_id=object_id('[dbo].[MaTable]') and index_id in (0,1)

Remarque : on utilise l’agrégat (SUM) afin de prendre en compte les tables partitionnées (dont les données sont sur plusieurs partitions).

Le plan d’exécution de cette requête, et surtout son coût, n’a absolument rien à voir !

Plan_SysViews

Au final, on constate bien que le fait de compter le nombre de lignes d’une table peut paraître trivial mais que la force brute n’est pas toujours la meilleure solution (dans le cas présent, le coût de la requête varie dans un ratio supérieur à 10 000 !).

Récemment, j’ai eu à intervenir sur un serveur sur lequel c’était ce type de requête qui étaient les plus coûteuses. Il convient donc de ne pas oublier ce « petit » raccourci …