2014-09-30 35 views
0

下面的MySQL查詢的工作方式如下: 在類樹形結構中,它搜索要使用的模板。優化MySQL查詢以獲取頁面的正確模板

例如:

  • 首頁(TPL:家) - (LVL:PAGID)
    • 卡魯塞爾(TPL:轉盤) - (LVL:SUBID)
    • 卡魯塞爾第1項(TPL: {從繼承父}) - (LVL:sub2Id)
  • 聯繫(TPL:接觸) - (LVL:PAGID)
    • ADDRES S(TPL:{從父母繼承}) - (LVL:SUBID)
  • 論壇(TPL:論壇) - (LVL:PAGID)
    • 主題(TPL:論壇) - (LVL:SUBID)
    • 消息(TPL:論壇) - (LVL:SUBID)
  • FAQ(TPL:FAQ) - (LVL:PAGID)
    • 問題1(TPL:問題) - (LVL:SUBID)
    • 問題2(tpl:問題) - (LVL:子ID)
    • Subquestion 1(TPL:{從繼承父}) - (LVL:sub2Id)
    • Subquestion 2(TPL:subquestion) - (LVL:sub2Id)

當一個孩子沒有templateId時,它繼承他父母的模板。 但是,當一個孩子有一個templateId,它保留自己的模板。

問題是下面的查詢的持續時間約爲1秒,這是一個經常在API中使用的查詢。如何優化下面的查詢而不失其工作?或者分割查詢會更好嗎?

SELECT 
         `c`.*, 
         `c`.`pagId` AS `parentPagId`, 
         `c`.`subId` AS `parentSubId`, 
         `c`.`sub2Id` AS `parentSub2Id`, 
         `c`.`sub3Id` AS `parentSub3Id`, 
         IF( 
          `template`.`templateName` IS NOT NULL, 
          `template`.`templateName`, 
          (
           SELECT 
            IF(
             `template`.`templateName` IS NOT NULL, 
             `template`.`templateName`, 
             'default' 
            ) 
           FROM 
            `content` 
           LEFT JOIN 
            `template` 
           ON 
            `content`.`templateId` = `template`.`id` 
           WHERE 
            CASE WHEN 
             (`content`.`sub3Id` = '' AND `content`.`sub2Id` != '' AND `content`.`templateId` != 0 AND `content`.`templateId` IS NOT NULL) 
            THEN 
             `content`.`sub2Id` = `c`.`sub2Id` 
            WHEN 
             (`content`.`sub2Id` = '' AND `content`.`subId` != '' AND `content`.`templateId` != 0 AND `content`.`templateId` IS NOT NULL) 
            THEN 
             `content`.`subId` = `c`.`subId` 
            WHEN 
             (`content`.`subId` = '' AND `content`.`pagId` != '' AND `content`.`templateId` != 0 AND `content`.`templateId` IS NOT NULL) 
            THEN 
             `content`.`pagId` = `c`.`pagId` 
            ELSE 
             '' 
            END 
           AND 
            `content`.`siteId` = '1' 
           AND 
            `content`.`langId` = '1' 
           AND 
            `content`.`active` = 1 
           LIMIT 1 
          ) 
         ) AS `template` 
        FROM 
         `content` `c` 
        LEFT JOIN 
         `template` 
         ON `c`.`templateId` = `template`.`id` 
        WHERE 
         `c`.`siteId` = '1' 
        AND 
         `c`.`langId` = '1' 
        AND 
         `c`.`active` = 1 
        ORDER BY 
         `c`.`order`, 
         `c`.`pagId`, 
         `c`.`subId`, 
         `c`.`sub2Id`, 
         `c`.`sub3Id` 

UPDATE
我有2個表:

表1( 「內容」)字段:

  • PAGID
  • 子ID
  • sub2Id
  • sub3Id
  • 內容
  • templateId

表2( 「模板」)字段:

  • ID
  • TEMPLATENAME

我想要做什麼(什麼工作,但在此查詢中花費的時間太多):

  1. 充分利用數據庫中的所有頁面
  2. 如果content.templateId> 0:從排得TEMPLATENAME template.id = content.templateId
  3. 如果content.templateId = 0或NULL:獲得父模板 - >這是子查詢做什麼...
  4. 如果模板沒有導致有效TEMPLATENAME:模板=「默認」

回答

0

您在這裏創建一個非常複雜的SQL命令。這沒有多大意義。當然,這並沒有幫助您的問題中缺少表格定義。我們應該猜測他們?

我很困惑,你有template.templateNametemplate.id,有時你使用一個,那麼其他?當你有它時總是使用id。它應該是一個唯一索引編號,而名稱可以是任何內容,甚至可能不是唯一的索引編號。

我很清楚你試圖在一個查詢中做太多事情。退一步,用簡單的步驟寫下你想要做什麼。

  1. 您似乎對每個頁面的內容都有一個「內容」表。如果它提到了一個模板,那麼你就完成了,得到它。

  2. 如果它沒有引用模板,請向父級提供它的模板。

它應該是那麼簡單。你可能應該在PHP中這樣做,並且只在需要時向數據庫詢問信息。您將被留下一個簡單的查詢:

SELECT * 
FROM content 
WHERE siteId = 1 AND langId = 1 AND active = 1 AND pagId = ? 

請注意,我只詢問我感興趣的網頁。我可能會誤解,但似乎你請求數據庫中的所有頁面。你可能只需要一個。