Оптимизация запроса MySQL, чтобы получить правильный шаблон для страницы

MySQL-запрос ниже работает так:
В древовидной структуре он ищет шаблон для использования.

Например:

  • Home (tpl: home) — (lvl: pagId)
    • Карусель (тпл: карусель) — (lvl: subId)
    • Элемент карусели 1 (tpl: {наследовать от родителя}) — (lvl: sub2Id)
  • Контакт (tpl: контакт) — (lvl: pagId)
    • Адрес (tpl: {наследовать от родителя}) — (lvl: subId)
  • Форум (tpl: форум) — (lvl: pagId)
    • Тема (tpl: форум) — (lvl: subId)
    • Сообщение (tpl: forum) — (lvl: subId)
  • FAQ (tpl: faq) — (lvl: pagId)
    • Вопрос 1 (tpl: question) — (lvl: subId)
    • Вопрос 2 (tpl: question) — (lvl: subId)
    • Подзапрос 1 (tpl: {наследовать от родителя}) — (lvl: sub2Id)
    • Подзапрос 2 (tpl: подзапрос) — (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`

ОБНОВИТЬ
У меня есть 2 таблицы:

Таблица 1 («контент») поля:

  • PAGID
  • Subid
  • sub2Id
  • sub3Id
  • содержание
  • templateId

Таблица 2 («шаблон») поля:

  • Я бы
  • Имя Шаблона

Что я хочу сделать (и что работает, но занимает слишком много времени в этом запросе):

  1. Получение всех страниц из базы данных
  2. Если content.templateId> 0: получить templateName из строки с template.id = content.templateId
  3. Если content.templateId = 0 или NULL: получить родительский шаблон -> это то, что делает подзапрос …
  4. Если шаблон не приводит к действительному templateName: template = «default»

0

Решение

Вы создали очень сложную команду SQL здесь. Это не имеет особого смысла. Конечно, не помогает, что определения таблиц отсутствуют в вашем вопросе. Мы должны их угадать?

Я в замешательстве, у вас есть template.templateName а также template.id, когда-нибудь вы используете один, потом другой? Всегда используйте id когда у тебя это есть. Это должно быть уникальное индексированное число, тогда как имя может быть любым и даже не может быть уникальным или индексированным.

Мне ясно, что вы пытаетесь сделать слишком много за один запрос. Сделайте шаг назад и запишите, простыми шагами, что именно вы хотите сделать.

  1. Кажется, у вас есть таблица содержимого для каждой страницы. Если это относится к шаблону, все готово, получите его.

  2. Если это не относится к шаблону, спросите у родителя его шаблон.

Это должно быть так просто. Вы, вероятно, должны делать это на PHP и запрашивать информацию у базы данных только тогда, когда это необходимо. Вы бы остались с одним простым запросом:

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

Обратите внимание, что я прошу только ту страницу, которая мне интересна. Я могу ошибаться, но, похоже, вы запрашиваете все страницы в базе данных. Вам, вероятно, нужен только один.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]