Comment trouver les objets inutilisés dans Power BI ?

J’utilise Semantic Link Labs pour repérer les tables, colonnes et mesures Power BI qui ne servent plus vraiment. L’intérêt, c’est d’arrêter de nettoyer au feeling. On part des rapports utilisés, des requêtes DAX récentes, puis on décide quoi garder ou supprimer.

Pourquoi chercher les objets inutilisés ?



C’est rarement le sujet le plus sexy, mais c’est souvent là que je gagne du temps sur un modèle Power BI. Un modèle sémantique, c’est la couche qui contient les tables, les colonnes, les relations et les mesures utilisées par les rapports. Quand cette couche grossit sans contrôle, elle devient vite difficile à lire, difficile à maintenir, et franchement pénible à faire évoluer.

Comment trouver les objets inutilisés dans Power BI ?

Je cherche les objets inutilisés parce qu’ils créent du bruit. Une colonne gardée “au cas où”, une mesure remplacée depuis six mois, une table de test jamais supprimée… Tout ça reste visible pour les développeurs, parfois pour les utilisateurs en libre-service, et ça finit par créer de la confusion. On ne sait plus quelle mesure utiliser. On duplique une logique déjà existante. On hésite à modifier un calcul parce qu’on ne sait pas s’il sert encore quelque part.

Côté data, le risque est clair : plus le modèle contient d’objets inutiles, plus il devient fragile. Une mesure peut sembler abandonnée, mais être encore appelée dans une autre mesure. Une colonne peut ne pas être visible dans un visuel, mais servir dans une relation, un tri ou une règle de sécurité. C’est pour ça qu’un objet détecté comme inutilisé n’est pas automatiquement à supprimer. C’est un candidat à vérifier.

Côté business, le problème est plus discret mais tout aussi réel. Les utilisateurs en libre-service ouvrent le modèle, voient dix variations de la même métrique, et ne savent pas laquelle prendre. Résultat, chacun construit sa version de la vérité. Et là, on perd la confiance.

Semantic Link Labs aide justement à objectiver ce nettoyage. Semantic Link Labs, c’est une boîte à outils qui permet d’analyser les modèles Power BI avec du code, notamment depuis Microsoft Fabric. Au lieu de dire “je pense que cette mesure ne sert plus”, on peut regarder les dépendances, les usages, les objets référencés ou non. Ça ne remplace pas le jugement humain, mais ça évite de nettoyer au doigt mouillé.

J’ai vu ça chez un client avec un modèle Power BI qui avait accumulé des dizaines de mesures jamais appelées dans les rapports récents. Personne n’osait les supprimer. Une fois la liste objectivée, on a pu trier calmement : à garder, à renommer, à archiver, à supprimer. Rien de magique, juste une base propre pour décider.

Objet inutiliséColonne, mesure ou table qui ne semble plus appelée dans les rapports ou les dépendances analysées.
RisqueConfusion, maintenance plus lente, doublons de mesures, et risque de casser un usage caché si on supprime trop vite.
Action recommandéeVérifier l’usage réel, valider avec les équipes métier, puis supprimer, archiver ou documenter selon le cas.


De quoi ai-je besoin avant l’analyse ?



Avant de chercher les objets inutilisés, je vérifie toujours que j’ai le bon terrain de jeu. Sinon on passe vite une heure à “analyser” un modèle alors qu’on n’a pas accès aux rapports, ou que la librairie Python du notebook n’a pas la bonne fonction disponible. Ça m’est déjà arrivé chez un client, et franchement, c’est le genre de détail bête qui bloque tout.

Comment trouver les objets inutilisés dans Power BI ?

Pour cette analyse, j’ai surtout besoin de trois choses : un modèle sémantique Power BI accessible depuis Fabric, un notebook capable d’exécuter du Python, et Semantic Link Labs. Semantic Link Labs est une bibliothèque Python pensée pour interroger et analyser des objets Power BI depuis un notebook. On l’importe souvent sous le nom sempy_labs.

ÉlémentPourquoi c’est nécessaire
Accès au workspaceJe dois pouvoir atteindre l’espace où se trouve le modèle sémantique.
Droit de lire le modèleSans accès en lecture, impossible d’inspecter les tables, colonnes, mesures et relations.
Notebook Fabric exécutableL’analyse se lance depuis un notebook, pas directement depuis Power BI Desktop.
Librairie Semantic Link Labs disponibleLa fonction d’analyse dépend de cette librairie Python, souvent importée avec sempy_labs.
Rapports en avalSi je veux savoir quels champs sont utilisés dans les visuels, il faut que les rapports soient accessibles aussi.

Je commence souvent par afficher la signature de la fonction. C’est tout simple, mais très utile. Les notebooks d’équipe ne sont pas toujours au même niveau de librairie, et les paramètres exacts peuvent changer selon l’installation. Plutôt que de deviner, je demande à Python ce que la fonction attend.

# J'importe Semantic Link Labs, souvent utilisé sous l'alias labs
import sempy_labs as labs

# J'importe inspect pour afficher les paramètres disponibles d'une fonction Python
import inspect

# J'affiche la signature de find_unused_objects
# Les paramètres exacts peuvent dépendre de la version installée dans le notebook
print(inspect.signature(labs.find_unused_objects))

Il y a aussi une autre approche, plus orientée usage réel. Je peux exploiter les requêtes DAX capturées via le Workspace Monitoring. Le DAX, c’est le langage utilisé par Power BI pour interroger le modèle. En regardant les requêtes réellement exécutées récemment, je vois quels objets ont été sollicités par les utilisateurs, pas seulement ceux référencés dans la structure des rapports.

Les deux approches se complètent bien. Semantic Link Labs aide à inspecter le modèle et les rapports. Le Workspace Monitoring aide à comprendre ce qui est vraiment utilisé dans la vraie vie. Et c’est souvent là que les surprises arrivent.



Comment lancer find_unused_objects ?



Je lance find_unused_objects depuis un notebook, surtout pour éviter de nettoyer un modèle Power BI à l’aveugle. Dans mon scénario simple, j’ai un modèle sémantique avec une table de personnes. Le rapport utilise la mesure Person Count et la dimension Gender. L’analyse doit donc me montrer que ces deux objets sont bien interrogés, pendant que d’autres colonnes, par exemple Birth Date, Middle Name ou Legacy Code, peuvent ressortir comme potentiellement inutilisées.

Le mot important, c’est potentiellement. Je ne supprime rien directement depuis ce notebook, je m’en sers pour créer une liste de vérification. J’ai déjà vu chez un client une colonne “inutile” utilisée uniquement dans un export mensuel, jamais dans les pages principales du rapport. Si on l’avait supprimée trop vite, on cassait un process métier discret mais bien réel.

Le widget peut aussi afficher les requêtes DAX récentes. DAX, c’est le langage de requête et de calcul utilisé par Power BI. Ça aide à comprendre ce qui a vraiment été interrogé dans le modèle, pas juste ce qu’on pense utiliser dans les visuels.

Voici le code que je mets dans un notebook. Je commence par afficher la signature de la fonction, parce que sempy_labs évolue et je ne veux pas promettre une signature figée.

import sempy_labs as labs
import pandas as pd
import inspect

# Je définis le workspace et le modèle sémantique à analyser.
workspace = 'Nom du workspace'
dataset = 'Nom du modèle sémantique'

# J'affiche la signature disponible dans mon environnement.
# Ça me permet de voir les paramètres réellement supportés.
print(inspect.signature(labs.find_unused_objects))

# J'appelle la fonction avec les paramètres classiques.
# Selon la version installée, le résultat peut être un widget ou un objet affichable.
result = labs.find_unused_objects(dataset=dataset, workspace=workspace)

# Si la fonction retourne un dataframe pandas, je l'affiche comme une table.
# Sinon, display affichera le widget ou l'objet retourné par la librairie.
if isinstance(result, pd.DataFrame):
    display(result)
else:
    display(result)

Quand la fonction permet de récupérer directement un dataframe, je préfère souvent cette variante. C’est plus simple à filtrer, exporter, comparer, ou transformer en checklist dans Excel, SharePoint ou un ticket Jira.

import sempy_labs as labs
import pandas as pd
import inspect

workspace = 'Nom du workspace'
dataset = 'Nom du modèle sémantique'

# Je récupère la signature pour adapter l'appel à ma version de sempy_labs.
signature = inspect.signature(labs.find_unused_objects)
print(signature)

# Je prépare les paramètres de base.
params = {
    'dataset': dataset,
    'workspace': workspace
}

# Exemple défensif : si ma version propose un paramètre de retour dataframe,
# je l'active sans casser le code sur les autres versions.
if 'return_dataframe' in signature.parameters:
    params['return_dataframe'] = True

result = labs.find_unused_objects(**params)

if isinstance(result, pd.DataFrame):
    display(result)
else:
    display(result)

Après ça, je regarde les objets marqués comme utilisés ou non utilisés. Si Person Count et Gender ressortent comme utilisés, c’est cohérent avec mon rapport. Pour les autres colonnes, je vérifie les exports, les bookmarks, les pages masquées, les rapports connectés au même modèle, et les usages ponctuels avant de toucher au modèle.



Comment interpréter les résultats ?



Je lis toujours ces résultats comme une liste de suspects, pas comme une vérité absolue. Un outil peut me dire “cet objet n’a pas été vu”, mais ça ne veut pas dire “cet objet ne sert à rien”. C’est une nuance importante, surtout dans Power BI où un même champ peut être utilisé dans un rapport, une mesure DAX, une règle de sécurité ou même un fichier Excel connecté au dataset.

Comment trouver les objets inutilisés dans Power BI ?

Quand je regarde la sortie, je sépare d’abord les types d’objets. Les tables, les colonnes et les mesures ne se traitent pas pareil. Une mesure est souvent plus critique, parce qu’elle peut encapsuler de la logique métier. Une colonne peut sembler inutile, mais être appelée dans une mesure DAX, dans une relation, ou dans une règle RLS. RLS veut dire Row-Level Security, c’est la sécurité qui filtre les données selon l’utilisateur connecté.

Dans l’exemple simple, Gender et Person Count apparaissent comme utilisés. C’est logique. Ils alimentent un visuel et on les retrouve aussi dans des requêtes DAX récentes. DAX, c’est le langage de calcul de Power BI. Si l’outil voit ces objets dans l’activité récente, je les considère comme vivants. À l’inverse, certaines colonnes peuvent ressortir comme inutilisées parce qu’elles n’ont pas été vues dans les rapports analysés, ni dans les requêtes observées sur la période.

Mais je reste prudent. Une colonne absente des rapports récents peut encore servir ailleurs. Par exemple dans un export mensuel, un rapport paginé, une règle RLS, un modèle Excel connecté, ou un usage rare mais important. J’ai déjà vu un client vouloir supprimer une colonne “inutilisée” qui servait uniquement au contrôle de gestion une fois par trimestre. L’outil avait raison techniquement. Le métier aurait hurlé deux semaines plus tard.

Ma méthode est simple. J’exporte le dataframe, c’est juste le tableau de résultats obtenu par le script. Puis je trie par type d’objet, je vérifie les dépendances, je regarde les mesures liées, et je demande confirmation au métier quand le doute existe. Si je ne suis pas sûr, je masque ou je renomme avant de supprimer. Moi, je ne supprime jamais une colonne juste parce qu’un outil me le dit.

  • Garder si l’objet est utilisé dans un visuel, une mesure, une relation, une règle RLS ou une requête récente.
  • Masquer si l’objet semble inutile côté rapport, mais pourrait encore servir techniquement.
  • Documenter si l’usage est rare, métier, ou difficile à détecter automatiquement.
  • Supprimer seulement si l’objet est confirmé inutile, sans dépendance, et validé par les personnes concernées.
DécisionQuand je l’applique
GarderObjet vu dans les rapports, les requêtes DAX, les mesures, les relations ou la sécurité.
MasquerObjet probablement inutile pour les utilisateurs, mais encore incertain techniquement.
DocumenterObjet peu utilisé, mais avec un usage métier spécifique ou ponctuel.
SupprimerObjet sans usage détecté, sans dépendance, et validé avant suppression.


Comment industrialiser le nettoyage ?



J’industrialise le nettoyage quand je ne veux plus dépendre d’un notebook lancé “quand quelqu’un y pense”. Le bon réflexe, c’est de transformer l’analyse des objets inutilisés en routine d’équipe. Pas juste un scan technique, mais un petit processus de gouvernance Power BI.

Concrètement, je lance l’analyse régulièrement, par exemple chaque semaine ou chaque mois, puis j’historise les résultats. Un dataframe, c’est simplement un tableau manipulable en Python, avec des lignes et des colonnes. Une table de suivi dans Fabric ou un fichier CSV fait très bien l’affaire au début.

Ce suivi me permet de comparer les objets dans le temps :

  • Un objet inutilisé sur un seul cycle peut être un faux positif.
  • Un objet inutilisé pendant trois ou quatre cycles mérite une décision.
  • Une mesure jamais utilisée mais référencée dans une autre mesure ne doit pas être supprimée trop vite.
  • Une colonne technique peut rester utile pour un traitement amont, même si elle n’apparaît dans aucun visuel.

J’ai déjà vu des équipes supprimer trop vite des mesures “orphelines”, puis casser un rapport exécutif le lundi matin. Depuis, je préfère ajouter une étape de validation. L’objet est détecté, historisé, puis un ticket est créé avant suppression. Le propriétaire du modèle valide ou refuse. Simple, mais ça évite les discussions floues.

ÉtapeBut
Exécution planifiéeLancer l’analyse sans action manuelle.
HistorisationVoir si l’objet reste inutilisé dans le temps.
Ticket de validationObtenir un accord avant suppression.
DocumentationGarder une trace claire dans le modèle sémantique.

Dans un notebook Fabric, j’utilise ce type de code quand le résultat de l’analyse est disponible dans une variable result. Il transforme le résultat en dataframe pandas, ajoute la date d’analyse, puis sauvegarde le suivi dans les fichiers du Lakehouse.

import pandas as pd
from datetime import datetime

# Transformer le résultat en dataframe pandas si ce n'est pas déjà le cas
df = result if isinstance(result, pd.DataFrame) else pd.DataFrame(result)

# Ajouter la date d'analyse pour historiser chaque exécution
df['analysis_date'] = datetime.utcnow()

# Sauvegarder le résultat dans le Lakehouse Fabric au format CSV
df.to_csv('/lakehouse/default/Files/powerbi_unused_objects.csv', index=False)

# Option possible dans Fabric si Spark est disponible :
# spark_df = spark.createDataFrame(df)
# spark_df.write.mode("append").saveAsTable("powerbi_unused_objects")

Après ça, je peux suivre les tendances. Si une mesure ressort inutilisée pendant plusieurs analyses, je la marque comme candidate à suppression. Si elle est validée, je la supprime proprement et je mets à jour la documentation du modèle sémantique, c’est-à-dire la couche Power BI qui contient les tables, relations, mesures et règles métiers.

Le vrai bénéfice, il est là. Votre modèle devient plus lisible, plus sûr à maintenir, et moins dépendant de la mémoire des personnes.



Qu’est-ce que je nettoie maintenant ?



Je nettoie d’abord ce que je comprends. Semantic Link Labs donne une vraie base pour repérer les objets inutilisés dans un modèle sémantique Power BI : tables, colonnes, mesures, usages dans les rapports, requêtes DAX récentes via Workspace Monitoring. Mais je garde une règle simple : l’outil propose, je valide. Le bon réflexe, c’est d’exporter les résultats, de les relire avec les dépendances, puis de décider quoi masquer, documenter ou supprimer. Vous gagnez un modèle plus clair, moins risqué à faire évoluer, et surtout plus simple à utiliser pour vos équipes.



FAQ



  • À quoi sert Semantic Link Labs dans Power BI ?
    Semantic Link Labs sert à travailler avec les modèles sémantiques Power BI depuis des notebooks. Dans ce cas précis, je m’en sers pour repérer les objets potentiellement inutilisés, comme des tables, colonnes ou mesures, et préparer un nettoyage plus fiable.
  • find_unused_objects supprime-t-il automatiquement les objets ?
    Non, et c’est mieux comme ça. La fonction aide à identifier des candidats à la suppression. La décision finale doit rester humaine, surtout si l’objet peut servir dans une mesure, une règle de sécurité, un rapport peu utilisé ou un usage externe.
  • Quelle est la différence entre l’analyse des rapports et l’analyse DAX ?
    L’analyse des rapports regarde la structure des rapports en aval pour voir quels objets sont utilisés dans les visuels. L’analyse DAX regarde les requêtes capturées, notamment via Workspace Monitoring, pour identifier les objets réellement sollicités récemment.
  • Pourquoi récupérer un dataframe pandas ?
    Le dataframe permet de sortir du simple affichage interactif. Je peux filtrer, trier, historiser les résultats, les exporter en CSV, les comparer dans le temps et créer un vrai processus de gouvernance autour du nettoyage du modèle.
  • Peut-on supprimer une colonne si elle apparaît inutilisée ?
    Je conseille de vérifier avant. Une colonne peut ne pas apparaître dans les rapports récents mais être utile ailleurs. Le bon réflexe, c’est de contrôler les dépendances, demander validation aux utilisateurs concernés, puis masquer ou documenter avant suppression si le doute existe.

 

 

A propos de l’auteur



Je suis Franck Scandolera, expert et formateur en tracking avancé server-side, Analytics Engineering, automatisation No/Low Code avec n8n, intégration de l’IA en entreprise et SEO/GEO. Je dirige l’agence webAnalyste et l’organisme Formations Analytics. J’accompagne des équipes data, marketing et business chez Logis Hôtel, Yelloh Village, BazarChic, la Fédération Française de Football, Texdecor et d’autres. Si vous voulez fiabiliser vos modèles Power BI, vos pipelines data ou vos automatisations IA, contactez-moi, je peux vous aider à structurer ça proprement.

Retour en haut
Formations Analytics