簡體   English   中英

如何優化SQL查詢

[英]How to optimize the sql query

此查詢將動態輸入替換為cg.ownerid IN(294777,228649,188464)。當IN條件下的輸入增加時,該查詢將花費太多時間來執行。 請建議我一種優化方法。

例如,下面的查詢需要4秒鍾,如果我將列表縮小為IN(188464),則只需1秒鍾。

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

由於我沒有進一步的信息,所以我建議您首先修改where子句。 當您離開這些列時,應將它們移至子查詢。

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

但是不確定是否所有內容都已立即連接,您缺少一些別名,這使我很難通過您的查詢。 但是我想你會明白的。 :-)

有了這么少的信息,就不可能給出任何具體的想法,但是通常的一般情況適用:

  1. 打開統計信息io並檢查導致大多數邏輯I / O的原因,然后嘗試解決該問題
  2. 查看實際計划,並檢查是否有看起來不正常的東西,例如:
    • 聚集索引/表掃描(新索引可以解決此問題)
    • 具有大量行的鍵查找(將更多列添加到索引可以解決此問題,無論是常規字段還是包含的字段)
    • 線軸(新索引可以解決此問題)
    • 估計的行數與實際的行數之間存在很大差異(10x,100x等)

為了給出更好的提示,您實際上應該至少在基本部分上包括實際的計划,表/索引結構,並告訴您太多的時間(秒,分鍾,小時?)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM