Query taking long time to run

Hi I have the following query which currently brings back 217,000 records taking almost 2 mins to run which is quite slow.

SELECT
b.LastName + ', ' + b.FirstName AS ClaimHandler
, c.[Claim Ref] AS ClaimRef
, c.Profession
, c.Insured
, c.ClientDivision
, c.ClientSiteOrAccidentLossLocation AS LossLocation
, c.DateOfCause
, c.DateNotified
, c.Status AS FileStatus
, c.DateClosed
, c.ClaimantName
, c.DetailsOfClaim AS Circumstances
, c.Paid AS ClaimPaid
, c.Reserve AS ClaimReserve
, c.Incurred AS TotalIncurred
, c.LatestDevelopments AS CurrentPosition
, c.matterType AS NotifiedType
, c.InsurerRef
FROM
ClaimData c LEFT JOIN CSL_LIB_DEV.dbo.Security_Users b ON b.ID = c.ClaimHandlerID
WHERE
DateClosed >= '11/02/2015' AND DateClosed <= '11/02/2025'
AND
DateNotified >= '11/02/2015' AND DateNotified <= '11/02/2025'

I'm not sure how I can go about speeding it up. Is this due to the large data being bought back as the query contains couple of text fields. I belive my date filter is ok.. Below is the execution plan link:

Can anyone help?

hi

hope this helps

1. Indexing

  • Create Indexes on Date Columns:
    • Add an index on DateClosed and DateNotified in the ClaimData table to speed up the WHERE clause filtering.

sql

CREATE INDEX IX_ClaimData_DateClosed ON ClaimData (DateClosed);  
CREATE INDEX IX_ClaimData_DateNotified ON ClaimData (DateNotified);  
  • Index the Join Column:
    • Ensure that ClaimHandlerID in ClaimData and ID in Security_Users are indexed for faster joins.

sql

CREATE INDEX IX_ClaimData_ClaimHandlerID ON ClaimData (ClaimHandlerID);  
CREATE INDEX IX_Security_Users_ID ON Security_Users (ID);  

2. Optimize the WHERE Clause

  • Use Efficient Date Formats:
    • Use the 'YYYY-MM-DD' format for dates to avoid any implicit conversions.

sql

WHERE DateClosed >= '2015-02-11' AND DateClosed <= '2025-02-11'  
AND DateNotified >= '2015-02-11' AND DateNotified <= '2025-02-11'  

3. Optimize the JOIN

  • Use INNER JOIN if Possible:
    • If all ClaimHandlerID values in ClaimData exist in Security_Users, consider using an INNER JOIN instead of LEFT JOIN for better performance.

sql

INNER JOIN CSL_LIB_DEV.dbo.Security_Users b ON b.ID = c.ClaimHandlerID  

4. Select Only Necessary Columns

  • Avoid Selecting Unnecessary Data:
    • Ensure that all selected columns are needed. Selecting fewer columns reduces the amount of data being transferred and processed.

5. Consider Partitioning

  • Partition the Table:
    • Partition the ClaimData table by DateClosed or DateNotified to improve query performance when filtering by these dates.

sql

-- Example partitioning by DateClosed  
CREATE PARTITION FUNCTION pf_DateClosed (DATE)  
AS RANGE RIGHT FOR VALUES ('2016-02-11', '2017-02-11', '2018-02-11', '2019-02-11', '2020-02-11', '2021-02-11', '2022-02-11', '2023-02-11', '2024-02-11', '2025-02-11');  

CREATE PARTITION SCHEME ps_DateClosed  
AS PARTITION pf_DateClosed  
ALL TO ('PRIMARY');  

CREATE TABLE ClaimData (  
    -- ... other columns ...  
    DateClosed DATE  
) ON ps_DateClosed (DateClosed);  

6. Update Statistics

  • Ensure Statistics Are Up-to-Date:
    • Regularly update statistics to help the query optimizer choose the most efficient execution plan.

sql

EXEC sp_updatestats;  

7. Analyze Execution Plan

  • Review the Execution Plan:
    • Use SQL Server Management Studio (SSMS) to analyze the query execution plan. Identify any table scans, inefficient joins, or other bottlenecks and address them accordingly.

8. Consider Implementing Pagination

  • Limit Record Retrieval:
    • If the application allows, implement pagination to retrieve records in smaller chunks, reducing the load on the database.

sql

SELECT ...  
FROM ...  
WHERE ...  
ORDER BY DateClosed OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY;  

9. Optimize Server Configuration

  • Ensure Adequate Resources:
    • Make sure the SQL Server has sufficient memory, disk space, and CPU resources to handle large queries efficiently.

10. Regular Maintenance

  • Maintain Indexes:
    • Periodically rebuild or reorganize indexes to maintain optimal performance.

sql

ALTER INDEX ALL ON ClaimData REBUILD;  

Final Optimized Query

Incorporating the above optimizations, the final query would look like this:

sql

SELECT   
    b.LastName + ', ' + b.FirstName AS ClaimHandler,  
    c.[Claim Ref] AS ClaimRef,  
    c.Profession,  
    c.Insured,  
    c.ClientDivision,  
    c.ClientSiteOrAccidentLossLocation AS LossLocation,  
    c.DateOfCause,  
    c.DateNotified,  
    c.Status AS FileStatus,  
    c.DateClosed,  
    c.ClaimantName,  
    c.DetailsOfClaim AS Circumstances,  
    c.Paid AS ClaimPaid,  
    c.Reserve AS ClaimReserve,  
    c.Incurred AS TotalIncurred,  
    c.LatestDevelopments AS CurrentPosition,  
    c.matterType AS NotifiedType,  
    c.InsurerRef  
FROM   
    ClaimData c   
INNER JOIN   
    CSL_LIB_DEV.dbo.Security_Users b ON c.ClaimHandlerID = b.ID  
WHERE   
    DateClosed >= '2015-02-11' AND DateClosed <= '2025-02-11'  
    AND DateNotified >= '2015-02-11' AND DateNotified <= '2025-02-11'  
ORDER BY   
    DateClosed;  
1 Like

Unfortunately, the plan doesn't show up when I go to Brent's site, square just spins and spins.

In general, then:

A) How many rows are in the Claim table? How many are there for 11 Feb 2015?
Without more info, you could try one index with DateNotified and DateClosed in it, e.g.:

CREATE
--UNIQUE
NONCLUSTERED INDEX ClaimData__IX_DateNotified_DateClosed
ON dbo.ClaimData ( DateNotified, DateClosed
--, [Claim Ref]
) WITH ( SORT_IN_TEMPDB = ON );

IF the [Claim Ref] column is unique, then add it to the nonclus index so that the index will be inherently unique (and "tell" SQL that it will be unique by adding the UNIQUE keyword; that is VERY important).

Also, when writing SQL against multiple tables, always alias every column in the query:

WHERE
c. DateClosed >= '11/02/2015' AND c. DateClosed <= '11/02/2025'
AND
c. DateNotified >= '11/02/2015' AND c. DateNotified <= '11/02/2025'

1 Like