Как оптимизировать самосоединение выбора с помощью внутреннего соединения с другой таблицей - PullRequest
0 голосов
/ 06 марта 2020

У меня есть доска объявлений с сообщениями, темами и досками, которые хранятся в одной таблице страниц. Я хотел бы перечислить все сообщения с их происхождением темы и доски. Самостоятельное соединение для этого выполняется быстро, но когда я включаю авторов сообщений, использующих внутреннее соединение, с другой таблицей, запрос замедляется до нескольких секунд. Есть ли способ улучшить структуру запроса?

База данных выглядит следующим образом:

pagetypes
type        | typename
———————————————————
15           board
16           thread
17           message 


pages
pageid  |  type | parentid    | authorid | title                
————————————————————————————————————————————
1          15      null          1        "BigBoard"
2          16      1             1        "Introductions"
3          17      2             2        “Hello everyone!”
4          17      2             1        “Welcome!”
5          16      1             1         “News and Gossip”
6          17      5             3        “Whats new?”

users
id    | name
————————————————————
1       "Peter"
2       "Paul"
3       "Mary"

Мой запрос на выборку:

select p.title as message_title, u.name, t.title as thread_title, b.title as board_title
from pages as p
join pages as t on p.parentid=t.pageid
join pages as b on t.parentid=b.pageid 
join users as u on p.authorid=u.id
where p.type=17

Результат выглядит следующим образом :

message_title       |   name    |   thread_title       |    board_title
-----------------------------------------------------------------------
“Hello everyone!”       Paul        "Introductions"         "BigBoard"
“Welcome                Peter       "Introductions"         "BigBoard"
“What’s new?””          Mary        "News and Gossip"       "BigBoard"

Если я заберу пользователя оттуда, запрос (на страницах 400 КБ) будет 30 мс. При добавлении пользователя в запрос запрос занимает до 3 секунд.

Вот описания таблиц:

CREATE TABLE `pages` (
  `pageid` int(10) unsigned NOT NULL DEFAULT '0',
  `parentid` int(10) unsigned NOT NULL DEFAULT '0',
  `authorid` int(10) unsigned NOT NULL DEFAULT '0',
  `type` smallint(5) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`pageid`),
  KEY `text_key` (`parentid`,`type`),
  KEY `type_key` (`type`),
  KEY `byAuthor` (`authorid`,`type`)
) 

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
)

1 Ответ

0 голосов
/ 06 марта 2020

Я думаю, что решил это. Я добавил LEFT JOIN для пользователей, которые сократили запрос до 30 мс.

select p.title as message_title, u.name, t.title as thread_title, b.title as board_title
from pages as p
join pages as t on p.parentid=t.pageid
join pages as b on t.parentid=b.pageid 
LEFT JOIN users as u on p.authorid=u.id
where p.type=17
...