2014-09-30 49 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 = ? 

请注意,我只询问我感兴趣的网页。我可能会误解,但似乎你请求数据库中的所有页面。你可能只需要一个。