Power BI Index Strategies

Posted by Ryan Alan on Aug, 13, 2019 11:08

Power BI is an amazing tool and is being used more and more by small and medium-sized businesses, but something that arises regularly, is the eventual sluggishness of both Power BI, as well as the databases it is connected to.  While this can be caused by many factors, I would like to go over the one I see the most, particularly with companies that do not have a dedicated DBA.

Note: Check out EPC Group’s Data Architecture Consulting Practice site for more information.

Index refreshing and rebuilding is one of those little processes that often either get forgotten or are not known about.  Many off the shelf CRM and Account Software that uses a SQL database will often have a large number of tables. Many of these tables, over an extended period, can become fragmented since indexes are used in almost every query to a database. The erosion of these indexes can start to become a major bottleneck in your processes.

So, what are indexes, what do they do, and how can one keep them clean?  In the next few paragraphs, I will give a quick overview and a few different solutions that can be used to help keep your business running quickly.

An index is exactly what it sounds like; it is a way for your database to locate data quickly by skipping over large chunks of a table that would otherwise have to be read line by line.  It does this the same way you would look at the index of a book and find a word or phrase and skip to that page of the book.  However, if the book keeps growing and words and phrases are just added to the end and not incorporated into the primary layout of the index then it becomes gradually more useless, and the time saving is lost.  That is what rebuilding or refreshing an index does.  It moves those entries from the back of the index to their proper location, thus restoring functionality.

Now that we know what the problem is, we will review three ways to remedy the situation. Please note that any index cleaning should be done during a non-peek time or off-hours, especially if you are not using enterprise editions of SQL Server.

1. Run the built-in software from the manufacturer.  Often CRM and Accounting software will include a maintenance utility that will fix this issue. However, many of those software’s are designed for enterprise solutions and not standard or express editions and running them during normal business hours will do one of two things. Either they will not do the maintenance requested, and mark it as a success, or will bring your organization’s database to a stop.

2. Manually checking index fragmentation of key tables.  This is the slowest method but does provide the most pinpointed effectiveness.  If you know which tables are constantly being updated or written into, then you can expand the table and right-click on the “Index”.Power Bi Index

  • Select the rebuild all indexes option, you will then be brought to the rebuild indexes wizard
  • From there, all you must do is click “OK.” If the fragmentation is less than 15% to 30%, then it will just refresh; however, if it is greater, it will rebuild the index, thus restoring functionality. Because I have a process that cleans all my indexes weekly the fragmentation is normally pretty light as the picture above shows.

3. SQL Statements. The last is more complex and will require someone with a strong knowledge of SQL statements and job creation. For this to work, you will need to write a stored procedure that goes through the system files of the database and looks for index fragmentation anything greater than 15% retrieves the index name and runs the SQL statement below for each index.

  • ALTER INDEX [index name here] ON [Database].[Schema].[Table] REBUILD;
  • Then you will want to create a job that runs this script over during your off-time hours. Then you will want to create a job that runs this script over during your off-time hours.

No matter which option you choose, it vital that a regular maintenance schedule is upheld so that performance can always be at its best.

[gravityforms id=41 title=”true” description=”false”]
<div class='gf_browser_chrome gform_wrapper exit_intent_popup_wrapper' id='gform_wrapper_41' ><form method='post' enctype='multipart/form-data' id='gform_41' class='exit_intent_popup' action='/power-bi-index-strategies/'> <div class='gform_heading'> <h3 class='gform_title'>Exit Intent</h3> <span class='gform_description'></span> </div> <div class='gform_body'><ul id='gform_fields_41' class='gform_fields top_label form_sublabel_below description_below'><li id='field_41_1' class='gfield gform_hidden field_sublabel_below field_description_below gfield_visibility_visible' ><input name='input_1' id='input_41_1' type='hidden' class='gform_hidden' aria-invalid="false" value='' /></li><li id='field_41_9' class='gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible' ><label class='gfield_label' for='input_41_9' >Full Name<span class='gfield_required'>*</span></label><div class='ginput_container ginput_container_text'><input name='input_9' id='input_41_9' type='text' value='' class='medium' placeholder='Full Name' aria-required="true" aria-invalid="false" /></div></li><li id='field_41_6' class='gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible' ><label class='gfield_label' for='input_41_6' >Email<span class='gfield_required'>*</span></label><div class='ginput_container ginput_container_email'> <input name='input_6' id='input_41_6' type='text' value='' class='medium' placeholder='Email Address' aria-required="true" aria-invalid="false" /> </div></li><li id='field_41_7' class='gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible' ><label class='gfield_label' for='input_41_7' >Phone<span class='gfield_required'>*</span></label><div class='ginput_container ginput_container_phone'><input name='input_7' id='input_41_7' type='text' value='' class='medium' placeholder='Phone Number' aria-required="true" aria-invalid="false" /></div></li><li id='field_41_10' class='gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible' ><label class='gfield_label' for='input_41_10' >Company Name<span class='gfield_required'>*</span></label><div class='ginput_container ginput_container_text'><input name='input_10' id='input_41_10' type='text' value='' class='medium' placeholder='Company Name' aria-required="true" aria-invalid="false" /></div></li><li id='field_41_8' class='gfield field_sublabel_below field_description_below gfield_visibility_visible' ><label class='gfield_label' for='input_41_8' >Message</label><div class='ginput_container ginput_container_textarea'><textarea name='input_8' id='input_41_8' class='textarea medium' placeholder='Type your message here...' aria-invalid="false" rows='10' cols='50'></textarea></div></li> </ul></div> <div class='gform_footer top_label'> <input type='submit' id='gform_submit_button_41' class='gform_button button' value='Submit' onclick='if(window["gf_submitting_41"]){return false;} window["gf_submitting_41"]=true; ' onkeypress='if( event.keyCode == 13 ){ if(window["gf_submitting_41"]){return false;} window["gf_submitting_41"]=true; jQuery("#gform_41").trigger("submit",[true]); }' /> <input type='hidden' class='gform_hidden' name='is_submit_41' value='1' /> <input type='hidden' class='gform_hidden' name='gform_submit' value='41' /> <input type='hidden' class='gform_hidden' name='gform_unique_id' value='' /> <input type='hidden' class='gform_hidden' name='state_41' value='WyJbXSIsIjEwNTJhNGVmMWMyNzI3YTJmMjdiZTA1NjU4ZDMzYzY3Il0=' /> <input type='hidden' class='gform_hidden' name='gform_target_page_number_41' id='gform_target_page_number_41' value='0' /> <input type='hidden' class='gform_hidden' name='gform_source_page_number_41' id='gform_source_page_number_41' value='1' /> <input type='hidden' name='gform_field_values' value='' /> </div> </form> </div><script type='text/javascript'> jQuery(document).bind('gform_post_render', function(event, formId, currentPage){if(formId == 41) {if(typeof Placeholders != 'undefined'){ Placeholders.enable(); }jQuery('#input_41_7').mask('(999) 999-9999').bind('keypress', function(e){if(e.which == 13){jQuery(this).blur();} } );} } );jQuery(document).bind('gform_post_conditional_logic', function(event, formId, fields, isInit){} );</script><script type='text/javascript'> jQuery(document).ready(function(){jQuery(document).trigger('gform_post_render', [41, 1]) } ); </script>