Showing posts with label SQL Server. Show all posts
Showing posts with label SQL Server. Show all posts

April 3, 2025

Mastering SQL Indexes: Boosting Database Performance with Smart Indexing

SQL indexing can be a game-changer for database performance, but its effectiveness hinges on how well you implement it. A while back, we faced a production database issue where queries were painfully slow, taking hours to complete. After some digging, we discovered that proper indexing was the key to solving the problem. This experience inspired me to dive deeper into SQL indexes, and in this guide, I’ll share what I’ve learned. We’ll cover the basics, explore how I used indexing to tackle a real-world challenge, and discuss the pros and cons to help you optimize your database effectively.


What is an Index in SQL?

An index in SQL is like the index in a book; it helps the database find data quickly without scanning every page (or row) in a table. Technically, it’s a database object created on one or more columns to improve the speed of data retrieval operations by providing an efficient way to locate data.


How Does It Work?

When you create an index on a column, the database builds a separate structure that organizes the data in that column for fast searching. Imagine a sorted list you can quickly reference instead of flipping through an entire unsorted table. Most databases use structures like B-trees behind the scenes, which allow for speedy lookups, inserts, and deletes. The result? The database can jump straight to the data it needs rather than checking every row.


Benefits of Indexing

Indexes turbocharge data retrieval, especially in large tables. Here’s how they shine:

  • Faster Searches: The database locates data quickly without a full table scan.
  • Quick Data Retrieval: Specific rows are fetched instantly using the index.
  • Better Query Performance: Queries with filters, sorts, or joins run more efficiently.
  • Easy Sorting: Indexed data can be pre-arranged, speeding up ORDER BY operations.


Understanding the Major Types of SQL Indexes

Choosing the right index depends on your application’s workload and query patterns. To make this clear, let’s break down the main types with examples.


Clustered Index

A clustered index dictates the physical order of data in a table, like a phone book sorted by last name. Since the data itself is stored in this order, a table can have only one clustered index. It is particularly useful for - 

 - Range queries (e.g., WHERE date BETWEEN '2023-01-01' AND '2023-12-31').
 - Primary key lookups (e.g., WHERE id = 123).

Non-Clustered Index

A non-clustered index is a separate structure from the table, like the index at the back of a book. It contains the indexed column values and pointers to the actual data rows. A table can have multiple non-clustered indexes. It is particularly useful for - 

 - Performing search on non-primary key columns (e.g., WHERE email = 'user@example.com').
 - Executing queries with WHERE, JOIN, or GROUP BY on non-clustered columns.

Unique Index

A unique index ensures no duplicate values exist in the indexed column(s), similar to a primary key but more flexible since it can apply to any column.

 - Example: A unique index on an email column prevents two users from registering with the same email address.

 - Best For: Enforcing data integrity (e.g., unique usernames or IDs).

Composite Index 

A composite index spans multiple columns, and the order of columns matters for query efficiency.

 - Example: In an orders table, a composite index on customer_id and order_date speeds up queries like WHERE customer_id = 100 AND order_date > '2023-01-01'.

 - Best for: Queries filtering or sorting on multiple columns.

Covering Index

A covering index (a type of non-clustered index) includes all columns a query needs, so the database can fetch everything from the index alone—like a mini-table.

 - Example: For SELECT first_name, email FROM users WHERE email = 'user@example.com', a covering index on email and first_name avoids accessing the full table.

 - Best For: Read-heavy queries retrieving multiple columns.

How I Optimized Indexing to Resolve a Major Database Performance Issue

Here’s a real-world example from my experience that shows indexing in action.

The Problem:

In our production environment, we had SQL jobs running stored procedures with data manipulation (DML) operations on tables holding 14 to 74 million rows. These jobs, which ran twice daily, took 7 to 9 hours to complete, unacceptable for our needs. The stored procedures also relied heavily on SQL functions, adding to the performance drag.

The Investigation:

We monitored the database and spotted a query with a staggering 2 billion logical reads. (Logical reads measure how many pages the database engine pulls from the buffer cache—a high number signals inefficiency.) This query was performing full table scans because the table lacked a non-clustered index on the columns in its WHERE clause.



The Solution:

We created a non-clustered index on the relevant columns. The impact was immediate: logical reads dropped dramatically, and query execution time shrank significantly.

Results:

To measure the improvement, we used SET STATISTICS IO ON; to track logical reads. Here’s the before-and-after:

Before:


After:



This fix not only sped up the jobs but also eased the load on the server.

When to Use Indexes

Indexes shine in these scenarios:

✅ Large Datasets: Speed up searches in tables with millions of rows.
✅ Frequent Filtering: Columns in WHERE, JOIN, or ORDER BY clauses.
✅ Uniqueness: Enforce constraints like unique emails or IDs.
✅ Primary/Foreign Keys: Often queried columns benefit from indexing.


When NOT to Use Indexes

Avoid indexes when:

🚫 Small Tables: The overhead outweighs the benefits for tiny datasets.

🚫 Heavy Writes: Indexes slow down INSERT, UPDATE, and DELETE operations since the index must be updated too.

🚫 Low-Cardinality Columns: Columns with few unique values (e.g., gender or status) don’t benefit much.

🚫 Temporary Tables: Indexing rarely justifies the cost for short-lived data.


Bringing It All Together

SQL indexing is a powerful tool for boosting database performance, but it requires a strategy. Index columns are frequently used in queries, especially for filtering, sorting, or joining, to unlock significant speed gains. However, avoid over-indexing: too many indexes can bloat storage and slow down write operations. By applying indexes thoughtfully, as we did to slash those 7-hour jobs, you can optimize performance without unnecessary overhead.

April 29, 2021

How to insert data into SQL Server Database Table using PowerShell?

Overview:

We implemented a PowerShell script for a Construction Engineering Company having headquarters in Boston, Massachusetts, United States; We came across a scenario was to insert records in MS SQL Server Database from the PowerShell script. In this blog, we will see how to enter data into the SQL Server - Database Table using PowerShell script. Let’s take an example of one real-life business use case.

Here we will have one table named “Employee” in SQL Server Database. We have two different columns named “EmpName” and “Designation”. We want to enter some Employee Information into this table. So, how can we achieve this using PowerShell?

Let’s get started! 
  1. Let’s define some variables to insert the values to SQL Server - Database Table. Here we have 5 variables for 'Server', 'Database', 'TableName', ‘EmpName’, and ‘Designation’.
  2.  $EmpName = 'Tejal','Khyati','Anikesh','Harsh'  
     $Designation = 'Developer'  
     $server = "Dev220"  
     $Database = "PoCDatabase"  
     $TableName = "dbo.Employee"  
    

  3. Establish a connection for the SQL Server database using the below code snippet. Here we use the ‘Server’ and ‘Database’ variables to generate connection string.
  4.  $Connection = New-Object System.Data.SQLClient.SQLConnection  
     $Connection.ConnectionString = "server='$Server';database='$Database';trusted_connection=true;"  
     $Connection.Open()  
     $Command = New-Object System.Data.SQLClient.SQLCommand  
     $Command.Connection = $Connection  
    

  5. We will apply a loop for each employee's name and execute the command for inset into the table.
  6.  foreach($Name in $EmpName){  
       $insertquery="   
       INSERT INTO $TableName  
           ([EmpName],[Designation])  
         VALUES   
           ('$Name','$Designation')"   
       $Command.CommandText = $insertquery  
       $Command.ExecuteNonQuery()  
     }  
    

    Here we use the Insert into query command and execute the command. This query will insert the Employee Name and Designation field values in the table.

  7. Close the connection of SQL. Use the following code snippet for the same.
     $Connection.Close();  
    

     Here is the complete code snippet to insert the data into the table.
  8.  $EmpName = 'Tejal','Khyati','Anikesh','Harsh'  
     $Designation = 'Developer'  
     $server = "Dev220"  
     $Database = "KDC"  
     $TableName = "dbo.Employee"  
     $Connection = New-Object System.Data.SQLClient.SQLConnection  
     $Connection.ConnectionString = "server='$Server';database='$Database';trusted_connection=true;"  
     $Connection.Open()  
     $Command = New-Object System.Data.SQLClient.SQLCommand  
     $Command.Connection = $Connection  
     foreach($Name in $EmpName){  
       $insertquery="   
       INSERT INTO $TableName  
           ([EmpName],[Designation])  
         VALUES   
           ('$Name','$Designation')"   
       $Command.CommandText = $insertquery  
       $Command.ExecuteNonQuery()  
     }  
     $Connection.Close();  

  9. Let’s execute our PowerShell script. This will insert the following code to SQL Server Database Table.


    Conclusion:

    This is how we can insert the data to SQL Server using PowerShell Script, hope this helps. Happy Scripting!!!

 If you have any questions you can reach out our SharePoint Consulting team here.

November 23, 2016

Default Print button in SSRS Report is not showing/working in Chrome and Firefox browsers

Scenario
SSRS toolbox provides Print functionality. But it's browser dependent. It works fine only with Internet Explorer browser, not compatible with Firefox and Chrome browsers.

Resolution
To achieve this, we've to use custom Print button and JavaScript code which executes on button click.

HTML code for Print button and Report viewer:
 <asp:Button runat="server" CssClass="btn-addschedule-bot" Style="margin-left: 10px;" ID="btnPrint" CausesValidation="true" ValidationGroup="vgSubmit" OnClientClick="printReportClick();" Text="Print Report" />  
 <div style="border: 1px solid #A7B0E8; margin: 0px 10px; padding: 5px; float: left;">  
 <rsweb:ReportViewer ID="rptViewer" runat="server" Height="500px" Style="-ms-overflow-y: scroll" Width="1100px" ShowToolBar="False" ShowParameterPrompts="False" ShowCredentialPrompts="False"></rsweb:ReportViewer>  
 </div>  

JavaScript Code to print a report in Chrome and Firefox:
 <script type="text/javascript">  
     function printReport(report_ID) {  
       var rv1 = $('#' + report_ID);  
       var iDoc = rv1.parents('html');  
       // Reading the report styles  
       var styles = iDoc.find("head style[id$='ReportControl_styles']").html();  
       if ((styles == undefined) || (styles == '')) {  
         iDoc.find('head script').each(function () {  
           var cnt = $(this).html();  
           var p1 = cnt.indexOf('ReportStyles":"');  
           if (p1 > 0) {  
             p1 += 15;  
             var p2 = cnt.indexOf('"', p1);  
             styles = cnt.substr(p1, p2 - p1);  
           }  
         });  
       }  
       if (styles == '') { alert("Cannot generate styles, Displaying without styles.."); }  
       styles = '<style type="text/css">' + styles + "</style>";  
       //--- Reading the report html  
       var table = rv1.find("div[id$='_oReportDiv']");  
       if (table == undefined) {  
         alert("Report source not found.");  
         return;  
       }  
       //-- Generating a copy of the report in a new window  
       var docType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">';  
       var docCnt = styles + table.parent().html();  
       var docHead = '<head><title>Printing ...</title><style>body{margin:5;padding:0;}</style></head>';  
       var winAttr = "location=yes, statusbar=no, directories=no, menubar=no, titlebar=no, toolbar=no, dependent=no, width=720, height=600, resizable=yes, screenX=200, screenY=200, personalbar=no, scrollbars=yes";;  
       var newWin = window.open("", "_blank", winAttr);  
       writeDoc = newWin.document;  
       writeDoc.open();  
       writeDoc.write(docType + '<html>' + docHead + '<body onload="window.print();">' + docCnt + '</body></html>');  
       writeDoc.close();  
       // The print event will fire as soon as the window loads  
       newWin.focus();  
       // uncomment to autoclose the preview window when printing is confirmed or canceled.  
       // newWin.close();  
     };  
     function printReportClick() {  
       printReport('<%=rptViewer.ClientID %>');  
     }  
   </script>  

Print Preview in Chrome browser:



I hope this will help you out to make print functionality working in Chrome and Firefox.

If you have any questions you can reach out our SharePoint Consulting team here.

October 30, 2013

Solution of the issue “field type is not installed properly. go to the list settings page to delete this field”

Problem :- “field type is not installed properly. go to the list settings page to delete this field”
Solution
Problem :- “field type is not installed properly. go to the list settings page to delete this field”
Solution
1.   Log In in SQL Server
2.   Select your appropriate database
3.   Go to query window and run following query.it will display all record which field have blank type.

   1:  Select Definition,* from dbo.ContentTypes where ISNULL(Definition,'0')<>'0' 
   2:   and Definition like '<Field Type=""%'
4.   Now run following query in your query window.it will delete all the site columns which field type is blank.

   1:  delete from dbo.ContentTypes where ISNULL(Definition,'0')<>'0' 
   2:   and Definition like '<Field Type=""%'
5.   Now check your site columns page URL (../_layouts/mngfield.aspx). Error will disappear.​

If you have any questions you can reach out our SharePoint Consulting team here.

August 28, 2013

Powershell Script Block To List ALL/Unused/Used Content Database


   1:  #Import Localized Data
   2:  #Import-LocalizedData -BindingVariable Message
   3:  Add-PsSnapin Microsoft.SharePoint.PowerShell
   4:  #This function is used to get standard content database list for Get-OSCContentDatabase
   5:  function Export-OSCContentDatabase
   6:  {
   7:  PARAM
   8:      (   
   9:          $ContentDatabases
  10:      )
  11:          $ContentDatabases | Select-Object -Property `
  12:                              @{Name="Url";Expression={
  13:                                  $_.WebApplication.Url
  14:                                                     }},`
  15:                              @{Name="ID";Expression={
  16:                                   $_.Id
  17:                                                     }},`
  18:                              @{Name="Name";Expression={
  19:                                   $_.Name
  20:                                                      }},`
  21:                              @{Name="WebApplication";Expression={
  22:                                   $_.WebApplication
  23:                                                      }},`
  24:                              @{Name="Server";Expression={
  25:                                   $_.Server
  26:                                                      }},`
  27:                              @{Name="CurrentSiteCount";Expression={
  28:                                   $_.CurrentSiteCount
  29:                                                      }},`
  30:                              @{Name="Status";Expression={
  31:                                   $_.Status
  32:                                   }} | Sort-Object -Property Name
  33:  }
  34:   
  35:  function Get-OSCContentDatabase
  36:  {          
  37:      [CmdletBinding(DefaultParameterSetName="UnUsedDatabase")]
  38:      PARAM
  39:          (
  40:              [Parameter(Mandatory=$false,Position=0,ParameterSetName='UsedDatabase')]
  41:              [switch]$UsedDatabase,
  42:              [Parameter(Mandatory=$false,Position=0,ParameterSetName='UnUsedDatabase')]
  43:              [switch]$UnUsedDatabase
  44:           )
  45:              [array]$arrContentDB = @()
  46:              try
  47:                  {
  48:                       Get-SPWebApplication -IncludeCentralAdministration | ForEach-Object{
  49:                       $arrContentDB += $_.ContentDatabases
  50:                                  }
  51:                  }
  52:                  catch [Exception]
  53:                  {
  54:                       #Catch and throw the terminating exception
  55:                       throw $Error[0].Exception.Message
  56:                  }
  57:                 
  58:                  #Check if content databases exist
  59:                  if($arrContentDB.Count -eq 0)
  60:                  {
  61:                       Write-Error $Message.NoContentDB
  62:                       return $null
  63:                  }
  64:                 
  65:                  $scriptContentDBOutput = @()
  66:                  $scriptContentDBOutput += Export-OSCContentDatabase $arrContentDB
  67:                 
  68:                  #List the content databases which are in use currently
  69:                  if($UsedDatabase)
  70:                  {
  71:                        Write-Host $Message.UsedDatabase
  72:                        $scriptContentDBOutput = $scriptContentDBOutput | Where-Object{$_.Status -eq "Online"}
  73:                        if($scriptContentDBOutput.Count -eq 0)
  74:                         {
  75:                            Write-Host $Message.ZeroUsedContentDB
  76:                            return $null
  77:                         }
  78:                  }
  79:                  #List the content databases which are not in use currently
  80:                  elseif($UnUsedDatabase)
  81:                  {
  82:                          Write-Host $Message.UnUsedDatabase
  83:                          $scriptContentDBOutput = $scriptContentDBOutput | Where-Object{$_.Status -ne "Online"}
  84:                          if($scriptContentDBOutput.Count -eq 0)
  85:                              {
  86:                                Write-Host $Message.ZeroUnusedContentDB
  87:                                return $null
  88:                               }
  89:                  }
  90:                  #List all content databases
  91:                  else
  92:                  {
  93:                          Write-Host $Message.AllDatabase
  94:                          if($scriptContentDBOutput.Count -eq 0)
  95:                            {
  96:                                Write-Host $Message.ZeroContentDB
  97:                                return $null
  98:                            }
  99:                  }
 100:                 
 101:                  $scriptContentDBOutput
 102:  }
 103:   
 104:  ##Uncomment Following Line to List Out All Content Database
 105:  Get-OSCContentDatabase
 106:   
 107:  ##Uncomment Following Line to List the content databases which are in use currently.
 108:  Get-OSCContentDatabase -UsedDatabase
 109:   
 110:  ##Uncomment Following Line to List the content databases which are not in use currently.
 111:  Get-OSCContentDatabase -UnUsedDatabase

If you have any questions you can reach out our SharePoint Consulting team here.

April 16, 2013

Database maintenance for SharePoint 2010 Products

Microsoft SharePoint 2010 databases are very large in size and it's essential to maintain it for smooth and faster database operations. SharePoint recommends following task to perform for SharePoint Database.
  • Check database integrity.
  • Defragment indexes by reorganizing them or rebuilding them.
  • Set the fill factor for a server.
Database maintenance task covers all required process to maintain SharePoint database. Database maintenance task can be performed by running database maintenance wizard or by running Transact-SQL commands. Transact-SQL commands are very complex and need deep knowledge of SQL commands and configuration. But SQL server management studio 2008 and 2005 covers database management wizard with very user friendly user interface. Here we will cover SharePoint database maintenance with maintenance plan wizard.
Do following process to run maintenance plan wizard with SQL Server Management studio 2008.
  • Open SQL Server management studio and do login.
  • Select Management and right click maintenance plans and Choose Maintenance Plan wizard.
  • Click next until select plan property page.

  • Give name and description as desired.
  • Select weather configures one or more maintenance plans.
    • To configure a single maintenance plan, select Single schedule for the entire plan or no schedule.
    • To configure multiple maintenance plans with specific tasks, select Separate schedules for each task.
  • For the database more than 10 content databases or having larger size of database, it is recommended to go for separate maintenance plans.
  • Click on change button to create a schedule or timer job to run maintenance plan.
  • It will open Job Schedule Properties dialog box.

    • Set schedule as per requirement.
    • After scheduling click OK and Next.
  • Next page is to select maintenance tasks page. This page will show the list of all maintenance tasks required for SharePoint Maintenance.

    Note:
    • Need to take care in selecting index reorganization or index rebuilding. A maintenance plan should include any one from index reorganization and index rebuilding, Not Both.
    • A maintenance plan should never include shrinking a database.
    • Maintenance cleanup task will remove files left after scheduled Maintenance.
    Select the tasks for the plan and click next.
  • Next page will be Select Maintenance Task Order Page.
    • You can change the order of the tasks in the plan on this page. Then click next.
  • Next page will be Database Check Integrity Task Page.

    • Select databases to reorganizing index and check compact large object check box. Then click ok.
  • Define Rebuild Index Task page
    • Select databases and configure as below. And click next.
  • Define Maintenance Cleanup Task page
    • Select options as required and click next.
  • Select Report Options
    • Give path to save log file.
  • Then click finish to start the maintenance plan process.
  • To shrink database do following process.
    • Start SQL server management studio 2008.
    • In Databases, select the database you want to shrink.
    • Right click the database, select tasks, Shrink, files.
    • Select the file type and file name.
    • Select reorganize files before releasing unused space.
    • Then click OK

If you have any questions you can reach out our SharePoint Consulting team here.

April 2, 2013

Steps to resolve “Can't connect the configuration database" Error in SharePoint

Steps to resolve “Can not connect to the configuration database Error in SharePoint

When we try to browse a SharePoint site, if it shows the following Error “Cannot connect to the configuration database”.

The reason you get the above message is that the SharePoint cannot connect to the SQL database. You need to check whether SQL Server Service is started or not. To check:-
Go to Start -- > Administrative Tools à Services
The following screen will be displayed showing all services. Now check “SQL Server (MSSQLSERVER) service”.

Need to start this Service as it is not started. Right Click on service and click on “Start”.

After starting the service you can see the status of the service is “Started” as shown in below screenshot.

Now, SharePoint site is opened Successfully.

If you have any questions you can reach out our SharePoint Consulting team here.

May 28, 2012

Generate test data using GenerateData.com

Introduction:
There are times when you need test data in order to test how your application scales. GenerateData.com helps you generate test data in many popular formats like html, xml, csv. excel etc. Let's see how we can use it.
How to:

  • Goto generatedata.com
  • Enter column name in column title and select Datatype from drop down.
  • For ID AutoIncrement Datatype is selected and in options (Start at ) 1 is entered because from which value user wants to start his id number.
  • And in increment it is given 1 because user wants to increase its id by 1.
  • Second field is inserted (Functional Group) whose DataType is custom list . The item of custom list is inserted in Enter values Seperated textbox and items should be separated by “|”.
  • If user has more rows then shown than user can add more values by entering exact figure and click on Row(s) textbox.​
  • After entering all data user has to select Result Type, For Result type option is given on top (HTML,Excel,XML,CSV,SQL), Select the desired Result Type. 
  • And finally click on generate button and if user has selected Excel for result type and an excel will generate and then user can import excel to Database.
Conclusion:
It is really easy and straight forward to genreate test data for almost any kind.
If you have any questions you can reach out our SharePoint Consulting team here.

February 21, 2012

Creating web application from existing content database

There are situations where you want to propagate one SharePoint web application
to some other farm/machine. I feel the fastest way is to take content database backup
and restore it in your destination farm. I have done so in last couple of weeks
and I have leaned how to quickly do that.
Here are quick notes from my experience:

Pre-requisites:
I was provided with content database backup and source code. That makes be able
to restore site and generate wsps from source code.
Creating content database from backup:

Go to your database server and do following:
  • Create a blank database that will be used as content database Restore a database
  • using content database back up from source farm.
Creating a web application:
  • Go to sharepoint central administration and create a new web application
  • While creating a new web application, use existing content database in database
    section
  • Sometimes if your database is too large, web application creation takes too long
    and times out. Don't worry at all. web application is still created successfully.
    It happened to me 4 times out of 5.
Validating the web application:
  • Go to sharepoint central administration, click on application management. In "Databases"
    section you will find "Manage content databases"
  • Choose your application and it will show database status and number of site collections.
    If you are not sure how many site collections are there in backup, anything greater
    than 0 is good news.
Configure web application to work properly:
we are almost done now. Do following:
  • Go to sharepoint central administration
  • Click on "Application Management"
  • In "Site Collections" section click on "Change site collection administrators"
  • choose your web application set proper data in site admins.
Additional optional steps:
After performing all the above steps, it is still possible that you are not able
to access your web application.
  • Last thing to do is to install and deploy wsp by using stsadm or your favorite method.
If you have any questions you can reach out our SharePoint Consulting team here.