выберите занять много времени на столе с множеством строк - PullRequest
0 голосов
/ 14 мая 2018

У меня есть этот выбор:

select 'like' prefix
     , l.post
     , l.data as data
     , l.user
     , concat(k.user, ' liked you') as logs 
  from likes l 

inner join posts p on l.post = p.id 
inner join cadastro k on l.user = k.id 
where p.user = 1 and l.user <> p.user

order by data desc
limit 10

прошло 2,3993 секунды.

enter image description here есть идеи по улучшению?

`likes` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `user` int(11) UNSIGNED NOT NULL,
  `post` int(11) UNSIGNED NOT NULL,
  `data` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `user_post` (`user`,`post`),
  KEY `post_user` (post, user),
  FOREIGN KEY (`user`) REFERENCES cadastro (`id`),
  FOREIGN KEY (`post`) REFERENCES posts (`id`) ON DELETE CASCADE
)

`posts` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,

`cadastro` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,

есть идеи, чтобы ускорить это? Я также пытался добавить индекс данных лайков, но различий не заметил.

Ответы [ 2 ]

0 голосов
/ 20 мая 2018
select  'like' prefix ,
        l.post ,
        l.data as data ,
        l.user ,
        ( SELECT concat(user, ' liked you')
              FROM cadastro  WHERE id = l.user ) AS logs
    from  likes l
    inner join  posts p  ON l.post = p.id
    where  p.user = 1
      and  l.user <> p.user
    order by  data desc
    limit  10

Индексы:

p: (user, data, id)  -- 'covering'; helps WHERE; may help ORDER BY
l: (post)
cadastro: I assume you have PRIMARY KEY(id)

Дальнейшее улучшение: измените индексы likes с

PRIMARY KEY (`id`),
UNIQUE KEY `user_post` (`user`,`post`),
KEY `post_user` (post, user),

до

PRIMARY KEY(post, user),
INDEX(user, post)

и избавиться от id.

Предостережение: если никто не понравился вам, результирующий набор может отличаться от этого запроса. Если это проблема, я переформулирую ее, чтобы использовать «производную» таблицу.

Перемещая поиск кадастров в подзапрос, я думаю, что действие происходит реже, чем если бы кадастр находился в JOIN. Это не универсальная оптимизация - обратите внимание, что предложение WHERE является сложным, поскольку оно включает в себя более одной таблицы. Мне неясно, будет ли индекс на p проходить через data, и поможет ли вообще с LIMIT. Для дальнейшего расследования, пожалуйста, предоставьте EXPLAIN FORMAT=JSON SELECT ...

0 голосов
/ 14 мая 2018

Это ваш запрос:

select 'like' as prefix, l.post, l.data as data, l.user,
        concat(k.user, ' liked you') as logs
from likes l join
     posts p
     on l.post = p.id oin
     cadastro k
     on l.user = k.id 
where p.user = 1 and l.user <> p.user
order by data desc
limit 10;

Для этого запроса вам нужны индексы на post(user, id), likes(post, user, data) и cadastro(id, user).

Вы не можете сделать много, чтобы удалить издержки для order by, но это должно ускорить объединение и фильтрацию частей запроса.

...