Оптимизация вложенного SQL запроса

349
06 января 2017, 10:01

Всем привет и с наступившим Новым Годом!

Теперь к вопросу: имеется sql запрос

SELECT `tema`.*, 
   (SELECT Count(*) 
    FROM   `post` 
    WHERE  `post`.`id_tema` = `tema`.`id`) AS `count_post`, 
   (SELECT `id` 
    FROM   `post` 
    WHERE  `post`.`id_tema` = `tema`.`id` 
    ORDER  BY `id` DESC 
    LIMIT  1)  AS `id_post`, 
   (SELECT `login` 
    FROM   `users` 
    WHERE  `users`.`id` = (SELECT `id_user` 
                           FROM   `post` 
                           WHERE  `post`.`id_tema` = `tema`.`id` 
                           ORDER  BY `id` DESC 
                           LIMIT  1)
   )  AS `login` 
FROM   `tema` 
WHERE  `id_forum` = '4' 
ORDER  BY `up` DESC, `time` DESC 
LIMIT  3260, 20 

Срок выполнения - 2.7 секунды.

Структура БД:

--
-- Структура таблицы `tema`
--
DROP TABLE IF EXISTS `tema`;
CREATE TABLE IF NOT EXISTS `tema` (
`id` int(11) NOT NULL auto_increment,
`id_razdel` int(11) NOT NULL,
`id_forum` int(11) NOT NULL,
`id_user` int(11) NOT NULL,
`name` varchar(500) NOT NULL,
`translate` varchar(500) NOT NULL,
`text` text NOT NULL,
`time` int(11) NOT NULL,
`up` enum('0', '1') NOT NULL default '0',
`closed` enum('0', '1') NOT NULL default '0',
`count` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `id_razdel` (`id_razdel`),
KEY `id_forum` (`id_forum`),
KEY `id_user` (`id_user`),
KEY `time` (`time`),
KEY `up` (`up`),
FULLTEXT KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Структура таблицы `post`
--
DROP TABLE IF EXISTS `post`;
CREATE TABLE IF NOT EXISTS `post` (
`id` int(11) NOT NULL auto_increment,
`id_razdel` int(11) NOT NULL,
`id_forum` int(11) NOT NULL,
`id_tema` int(11) NOT NULL,
`id_user` int(11) NOT NULL,
`text` text NOT NULL,
`cit` int(11) NOT NULL,
`time` int(11) NOT NULL,
`timeedit` int(11) NOT NULL,
`kedit` int(11) NOT NULL,
`id_user_edit` int(11) NOT NULL,
`vote` varchar(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_razdel` (`id_razdel`),
KEY `id_forum` (`id_forum`),
KEY `id_tema` (`id_tema`),
KEY `id_user` (`id_user`),
KEY `time` (`time`),
FULLTEXT KEY `text` (`text`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Explain запроса

Собственно вопрос: как можно оптимизировать данный sql запрос?

Answer 1

Не надо писать такие страшные запросы!

У вас есть отдельная таблица tema в которую заносите (соответствующие поля добавьте для этого) количество постов в теме, id последнего поста, id и логин юзера последнего поста и т.д. и т.п. при добавлении/удалении последнего поста темы. Так вы получите значительно меньшую нагрузку на базу.

P.S. Количество постов в теме еще при удалении любого поста в ней нужно будет изменить.

Answer 2

В общем сделал как и посоветовали.

В таблице tema добавил 3 поля: id_user_last, id_post_last, countpost. При добавлении нового поста они обновляются. При удалении также.

И сам запрос получился короче:

    SELECT `tema`.*,
     `users`.`login`
       FROM `tema` LEFT JOIN `users` ON `tema`.`id_user_last` = `users`.`id` 
        WHERE `id_forum`='4' ORDER BY `up` DESC, `time` DESC LIMIT 3260, 20

Работает в разы быстрее и при большем кол-ве данных.

READ ALSO
Получить следующую запись по ID

Получить следующую запись по ID

Известен idЕсть таблица где Id, title

286
Java - создание графического интерфейса [требует правки]

Java - создание графического интерфейса [требует правки]

Учусь создавать приложения на JavaВозник такой вопрос: на чем лучше создавать графический интерфейс? Делал 2 пробных проекта с GUI, используя...

352
Экзаменационное задание по программированию на Java [требует правки]

Экзаменационное задание по программированию на Java [требует правки]

Привет, есть экзаменационное задание по JavaНадо дописать частично написанную программу, текста самой программы нет, есть только jar файл с кучей...

501