[Solved] How can I optimize the execution time of this query?

How to optimize this SQL query?

In case you have your own slow SQL query, you can optimize it automatically here.

For the query above, the following recommendations will be helpful as part of the SQL tuning process.
You'll find 3 sections below:

  1. Description of the steps you can take to speed up the query.
  2. The optimal indexes for this query, which you can copy and create in your database.
  3. An automatically re-written query you can copy and execute in your database.
The optimization process and recommendations:
  1. Avoid Calling Functions With Indexed Columns (query line: 59): When a function is used directly on an indexed column, the database's optimizer won’t be able to use the index. For example, if the column `Field1_1` is indexed, the index won’t be used as it’s wrapped with the function `UPPER`. If you can’t find an alternative condition that won’t use a function call, a possible solution is to store the required value in a new indexed column.
  2. Avoid LIKE Searches With Leading Wildcard (query line: 59): The database will not use an index when using like searches with a leading wildcard (e.g. '%abc%'). Although it's not always a satisfactory solution, please consider using prefix-match LIKE patterns (e.g. 'TERM%').
  3. Avoid Subqueries (query line: 9): We advise against using subqueries as they are not optimized well by the optimizer. Therefore, it's recommended to join a newly created temporary table that holds the data, which also includes the relevant search index.
  4. Create Optimal Indexes (modified query below): The recommended indexes are an integral part of this optimization effort and should be created before testing the execution duration of the optimized query.
Optimal indexes for this query:
ALTER TABLE `CMS_Correspondence_Primary` ADD INDEX `cms_primary_idx_field12_1_field0_field1_1` (`Field12_1`,`Field0`,`Field1_1`);
ALTER TABLE `Items` ADD INDEX `items_idx_itemid_status` (`ItemId`,`Status`);
ALTER TABLE `Links` ADD INDEX `links_idx_parenttype_parentid` (`ParentType`,`ParentId`);
The optimized query:
SELECT
        SHOWN0,
        SHOWN1,
        LVL_1,
        LVL_2,
        LVL_3,
        LVL_4 
    FROM
        (SELECT
            CMS_Correspondence_Primary.Field0 SHOWN0,
            CMS_Correspondence_Primary.Field1_1 SHOWN1,
            (SELECT
                L.LEVEL 
            FROM
                Links L 
            WHERE
                L.ParentType = 1 
                AND L.ParentId = 'UG205' START WITH L.ItemId = Items.ItemId CONNECT 
            BY
                L.ItemId = PRIOR L.ParentId 
                AND PRIOR L.ParentType = 2) LVL_1,
            (SELECT
                L.LEVEL 
            FROM
                Links L 
            WHERE
                L.ParentType = 1 
                AND L.ParentId = 'UG206' START WITH L.ItemId = Items.ItemId CONNECT 
            BY
                L.ItemId = PRIOR L.ParentId 
                AND PRIOR L.ParentType = 2) LVL_2,
            (SELECT
                L.LEVEL 
            FROM
                Links L 
            WHERE
                L.ParentType = 1 
                AND L.ParentId = 'UG230' START WITH L.ItemId = Items.ItemId CONNECT 
            BY
                L.ItemId = PRIOR L.ParentId 
                AND PRIOR L.ParentType = 2) LVL_3,
            (SELECT
                L.LEVEL 
            FROM
                Links L 
            WHERE
                L.ParentType = 1 
                AND L.ParentId = 'UG281' START WITH L.ItemId = Items.ItemId CONNECT 
            BY
                L.ItemId = PRIOR L.ParentId 
                AND PRIOR L.ParentType = 2) LVL_4 
        FROM
            Items,
            CMS_Correspondence_Primary 
        WHERE
            (
                (
                    (
                        UPPER(CMS_Correspondence_Primary.Field1_1) LIKE UPPER('%abc%') 
                        AND CMS_Correspondence_Primary.Field1_1 IS NOT NULL
                    )
                ) 
                AND (
                    (
                        CMS_Correspondence_Primary.Field12_1 = 210
                    ) 
                    AND (
                        1 = 1
                    ) 
                    AND (
                        1 = 1
                    ) 
                    AND (
                        1 = 1
                    ) 
                    AND (
                        1 = 1
                    )
                )
            ) 
            AND (
                Items.Status <> 1
            ) 
            AND (
                Items.ItemId = CMS_Correspondence_Primary.Field0
            )
        ) INNER_QUERY 
    WHERE
        LVL_1 IS NULL 
        AND LVL_2 IS NULL 
        AND LVL_3 IS NULL 
        AND LVL_4 IS NULL

Related Articles



* original question posted on StackOverflow here.