Analysis Services Multidimensional models index fact partition data by every dimension attribute by default. When queries slice by a dimension member, these indexes allow the server to scan only the fact partition segments which contain data for that dimension member. Indexes are helpful to query performance (on one large cube, queries performed 40% slower without any indexes).
These indexes are rebuilt during cube processing during the ProcessIndexes phase. For example, ProcessFull on a partition will build these indexes. Also, when you ProcessUpdate a dimension, indexes and flexible aggregations for all partitions are dropped when dimension rollups change, necessitating they be rebuilt with a subsequent ProcessIndexes command. On large cubes, significant time can be spent on building indexes during processing. Also, on committing cube processing transactions on large cubes, hundreds of thousands of index files can slow down the commit as Andrew Calvett describes.
Specific indexes can be disabled by setting AttributeHierarchyOptimizedState to NotOptimized. In cubes with hundreds of dimension attributes, deciding which indexes are needed and disabling the unused indexes is a very tedious task. This BI Developer Extensions Delete Unused Indexes feature exists to automate this task.
These indexes are the *.map files and often can consume more space than the leaf level partition data (the .fact.data file). For example, in the following screenshot, notice the partition data is 883KB and there are several large indexes. One attribute in the Internet Sales Order Details dimension generates a 201KB index and another from the same dimension generates a 107KB index. An attribute in the Customer dimension generates a 95KB index, etc.
After analyzing the complete workload of queries, the BI Developer Extensions Delete Unused Indexes feature was able to disable indexes on many dimension attributes. None of the largest indexes were being used, and deleting them saves disk space and processing time. You can see in the following screenshot, the number of files in this partition went from 247 to 29:
In Solution Explorer, right click on the cube and choose Delete Unused Indexes:
This feature needs Profiler data. BI Developer Extensions can create a new trace against the server you have set in the project deployment properties. You can also point BI Developer Extensions at a SQL Server table containing a previously logged set of Profiler trace events. Regardless of which option you choose, make sure BI Developer Extensions sees the complete workload of queries against the cube since this feature will disable any indexes not being used during the queries logged.
If you point BI Developer Extensions at a SQL table, make sure the table contains the following events:
And capture the following columns:
Note: The SQL table can be a view. In scenarios where there are a few queries users or queries you wish to exclude from consideration, you can create a view to filter the data before presenting it to BI Developer Extensions.
Once it has finished collecting and analyzing trace events, it will provide the following summary of dimension attributes:
Make sure that the Subcubes counter in the top right is > 0 reflecting it has captured some Query Subcube Verbose events.
For any dimension attributes that have a checkmark next to them, BI Developer Extensions will disable index building when you click OK. For dimension attribute with the checkbox unchecked, BI Developer Extensions will ensure that indexing is enabled.
The green highlighted attributes are currently indexed but the index was not used during the profiler trace BI Developer Extensions analyzed. BI Developer Extensions will mark these attributes with a checkmark.
The red highlighted attributes are currently not indexed but the queries observed during the profiler trace would have used the index if it had been built. BI Developer Extensions will uncheck these so that it will re-enable indexing when you click OK.
The gray text attributes have indexing currently disabled.
Once you click OK and once you deploy your changes to the server, you will need to reprocess your cube for index files to be deleted. The easy way is to simply ProcessFull the cube. The more complex but efficient (since it doesn’t need to reread the data from the relational database) way is to run ProcessClearIndexes and ProcessIndexes in a transaction using the following example. (ProcessIndexes alone will not drop indexes that have been disabled.)
Then retest your query workload for performance to ensure no queries slow down after the recommended indexes are disabled. See the Testing section below for information on properly testing.
Clicking the Export button will put a tab delimited table of data in your clipboard. This table represents the recommendations BI Developer Extensions made, not any checkboxes you have subsequently checked or unchecked. You may paste into Excel and sort and format further.
The export contains the following columns.
The ClearCache XMLA statement will clear most SSAS caches. Unfortunately, it does not evict fact partition index files from the FileStores cache.
The only reliable way to evict index files from the cache is to restart the SSAS instance. To reliably test query performance before and after disabling indexes, we suggest you restart SSAS, clear the Windows system file cache, then run your query workload. Here is the complete, step-by-step testing outline:
The Query Subcube Verbose trace event is the key to detecting which indexes Analysis Services uses during queries. The following is an example:
Dimension 1 [Source Currency](Source-Currency)(Source-Currency) (0 0) [Source Currency Code](Source-Currency-Code):0 [Source Currency](Source-Currency)(Source-Currency):0
Dimension 2 [Destination Currency](Destination-Currency)(Destination-Currency) (13 0 0) [Destination Currency](Destination-Currency)(Destination-Currency):[US Dollar](US-Dollar) [Destination Currency Code](Destination-Currency-Code):0 [?](_):0
Dimension 3 [Date](Date)(Date) (0 39) [Fiscal Year](Fiscal-Year):0 [Date](Date)(Date):[October 20, 2007](October-20,-2007)
Dimension 4 [Geography](Geography) (0 + * 0 0) [City](City):0 [State-Province](State-Province):+ [Country](Country):* [Postal Code](Postal-Code):0 [Geography Key](Geography-Key):0
Between the parentheses, the following values can appear:
Symbol | Description | Index Used? |
---|---|---|
* | all of the members are requested | No |
+ | some but not all of the members are requested | Yes |
0 | this subcube doesn’t slice by this attribute | No |
1 | this subcube requests the all member | No |
number > 1 | this subcube requests this specific member | Yes |
- | below granularity slice | Yes |
So in the example above, the following indexes are used:
[Destination Currency](Destination-Currency)(Destination-Currency).[Destination Currency](Destination-Currency)(Destination-Currency), [Date](Date)(Date).[Date](Date)(Date), and [Geography](Geography).[State-Province](State-Province)
To disable an index, BI Developer Extensions will set the AttributeHierarchyOptimizedState to NotOptimized on the cube dimension attribute. If that dimension attribute is in a hierarchy, the OptimizedState property of that cube hierarchy will be set to NotOptimized (since indexes are always built for levels in hierarchies unless OptimizedState=NotOptimized on the hierarchy).
To enable an index, BI Developer Extensions will ensure AttributeHierarchyOptimizedState is FullyOptimized on the dimension attribute (seen under the dimension designer, not the cube designer, because if a dimension attribute is NotOptimized, it cannot be set to FullyOptimized using the cube attribute’s properties). Then BI Developer Extensions ensures the cube attribute’s AttributeHierarchyOptimizedState is set to FullyOptimized.
To view the cube attribute and cube hierarchy properties, look in the bottom left corner of the cube designer in BIDS or SSDTBI. We also recommend you run the Dimension Optimization Report and read that documentation page to further explain the rules around when indexes are built.
The Query Begin event is also parsed and if it is a drillthrough query, the Query Subcube Verbose events are skipped for that query. Drillthrough queries set the slice on most attributes and would cause BI Developer Extensions to rarely recommend disabling any indexes. Test performance of drillthrough queries before and after disabling indexes.