Rules / Maintenance

Remove unnecessary columns

warning UNNECESSARY_COLUMNS · ported · model layer · scope: Column, CalculatedColumn, CalculatedTableColumn

What it checks

Hidden columns, or columns in hidden tables, that nothing references: no DAX expression, relationship, hierarchy, sort-by column, group-by column, calendar, row-level security filter, or object-level security rule.

Each finding names the column, as 'Sales'[Legacy Region Code].

Example

Fires the rule
table Sales
	column 'Order ID'
		dataType: int64
		sourceColumn: OrderID

	column Amount
		dataType: decimal
		sourceColumn: Amount

	column 'Legacy Region Code'
		dataType: string
		isHidden
		sourceColumn: LegacyRegionCode

	measure 'Total Sales' = SUM('Sales'[Amount])
		formatString: #,0
After the fix
table Sales
	column 'Order ID'
		dataType: int64
		sourceColumn: OrderID

	column Amount
		dataType: decimal
		sourceColumn: Amount

	measure 'Total Sales' = SUM('Sales'[Amount])
		formatString: #,0

Why it matters

A hidden column that nothing uses is loaded, compressed, and refreshed for no reader. Key columns and helper columns pile up this way as a model evolves, and each one costs memory and refresh time in proportion to its cardinality. Removing them is the cheapest model diet there is.

How to fix it

For a data column, stop loading it: in Power BI Desktop, Transform data, select the query, and use Choose Columns or Remove Columns, so the column never reaches the model. Where the query reads a view or a stored procedure, drop it from the select list there instead and the refresh gets shorter too. For a calculated column, right-click it in the Data pane and choose Delete from model, or remove its column block from the table's TMDL file. If the column turns out to be needed after all, clear Is hidden in the Properties pane, or remove isHidden from under the column in the file, and the finding goes with it.

When to ignore it

Report usage is the case to check first. A hidden column that a visual, a slicer, or a report-level filter binds to is in use, but this rule reads the model only, as the source rule does, so it reports that column all the same. When the report is in the input, NOT_REACHED_FROM_REPORT says which fields that report never reaches; other reports on the same model are still yours to open before you delete anything. A column named as the default column of a variation is in the same position: the rule does not read variations, so it reports one that Power BI Desktop is quietly relying on. A staging column you are about to reference is a fair thing to leave for a week. A hidden key that no relationship uses is not: that one is what the rule is for.

To ignore this rule on one object, add annotation pbiplint.ignore = UNNECESSARY_COLUMNS under the object in its TMDL file. Power BI Desktop keeps the annotation. To turn the rule off for a whole project, set "UNNECESSARY_COLUMNS": "off" under rules in pbiplint.config.json.

Quirks

Ported from Microsoft's Best Practice Analyzer ruleset (opens in a new tab).

Check a model for this Improve this page (opens in a new tab)