1

This query takes dynamic input in the place of cg.ownerid IN (294777,228649 ,188464).when the input increases in the IN condition the query is taking too much time to execute. Please suggest me a way to optimize it.

For example, the below query is taking 4 seconds, if I reduce the list to just IN(188464) its just taking 1 second.

SELECT *
FROM
  (SELECT *,
          Row_number() OVER(
                            ORDER BY datecreated DESC) AS rownum
   FROM
     (SELECT DISTINCT c.itemid,
                      (CASE WHEN (Isnull(c.password, '') <> '') THEN 1 ELSE 0 END) AS password,
                      c.title,
                      c.encoderid,
                      c.type,
                      (CASE WHEN c.author = 'education' THEN 'Discovery' ELSE c.type END) AS TYPE,
                      c.publisher,
                      c.description,
                      c.author,
                      c.duration,
                      c.copyright,
                      c.rating,
                      c.userid,
                      Stuff(
                              (SELECT DISTINCT ' ' + NAME AS [text()]
                               FROM firsttable SUB
                               LEFT JOIN secondtable AS rgc ON thirdtable = rgc.id
                               WHERE SUB.itemid = c.itemid
                                 FOR xml path('')), 1, 1, '')AS [Sub_Categories]
      FROM fourthtable AS cg
      LEFT JOIN item AS c ON c.itemid = cg.itemid
      WHERE Isnull(title, '') <> ''
        AND c.active = '1'
        AND c.systemid = '20'
        AND cg.ownerid IN (294777,
                           228649,
                           188464)) AS a) AS b
WHERE rownum BETWEEN 1 AND 32
ORDER BY datecreated DESC
3
  • how did you take dynamic inputs ?? ownerid is varchar ??? did you split those and use ?? or taken data from some subquery something like that ?? Commented Jun 15, 2015 at 14:01
  • Do the WHERE plus the ROW_NUMBER first (on c and cg, in a CTE or Derived Table) and after reducing the number of rows to 32 you do the STUFF. Btw, your LEFT JOIN is actually an INNER JOIN due to the WHERE-condition on c Commented Jun 15, 2015 at 14:04
  • ownerid is received as list of varchar data from User Interface. Commented Jun 15, 2015 at 15:24

2 Answers 2

2

As I haven't further information, I just would suggest a first change of your where clause. They should be moved to a subquery as you left join those columns.

SELECT *
FROM(
    SELECT *,
    Row_number() OVER(
    ORDER BY datecreated DESC) AS rownum
    FROM
    (SELECT DISTINCT c.itemid,
    (CASE WHEN (Isnull(c.password, '') <> '') THEN 1 ELSE 0 END) AS password,
    c.title,
    c.encoderid,
    c.type,
    (CASE WHEN c.author = 'education' THEN 'Discovery' ELSE c.type END) AS TYPE,
    c.publisher,
    c.description,
    c.author,
    c.duration,
    c.copyright,
    c.rating,
    c.userid,
    Stuff(
        (
            SELECT DISTINCT ' ' + NAME AS [text()]
            FROM firsttable SUB
            LEFT JOIN secondtable AS rgc ON thirdtable = rgc.id
            WHERE SUB.itemid = c.itemid
            FOR xml path('')
        ), 1, 1, ''
    ) AS [Sub_Categories]
    FROM (
        SELECT cg.itemid
        FROM fourthtable as cg
        WHERE cg.ownerid IN (294777,228649, 188464)
    ) AS cg
    LEFT JOIN (
        SELECT DISTINCT c.itemid, c.type, c.author, c.title, c.encoderid, c.type, c.publisher, c.description, c.author, c.duration, c.copyright, c.rating,c.userid
        FROM item as c
        WHERE Isnull(c.title, '') <> ''
        AND c.active = '1'
        AND c.systemid = '20'
    ) AS c 
        ON c.itemid = cg.itemid
    ) AS a
) AS b
WHERE rownum BETWEEN 1 AND 32
ORDER BY datecreated DESC

But not quite sure if everything is connected right away, your missing some aliases which makes it hard for me to get through your query. But I thing you'll get my idea. :-)

Sign up to request clarification or add additional context in comments.

Comments

0

With this little information it's impossible to give any specific ideas, but the normal general things apply:

  1. Turn on statistics io and check what's causing most of the logical I/O and try to solve that
  2. Look at the actual plan and check if there's something that doesn't look ok, for example:
    • Clustered index / table scans (new index could solve this)
    • Key lookups with a huge amount of rows (adding more columns to index could solve this, either as normal or included fields)
    • Spools (new index could solve this)
    • Big difference between estimated and actual number of rows (10x, 100x and so on)

To give any better hints you should really include the actual plan, table / index structure at least on the essential parts and tell what is too much time (seconds, minutes, hours?)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.