выберите 8 секунд.улучшить идеи - PullRequest
0 голосов
/ 11 июня 2018

У меня есть этот выбор, чтобы получить чат (например, входящие Facebook).Он будет отображать самые последние сообщения, сгруппированные по пользователю, который их отправил.

SELECT c.id, c.from, c.to, c.sent, c.message, c.recd FROM chat c 
WHERE c.id IN(
  SELECT MAX(id) FROM chat
  WHERE (`to` = 1 and `del_to_status` = '0') or (`from` = 1 and `del_from_status` = '0')
  GROUP BY CASE WHEN 1 = `to` THEN `from` ELSE `to` END
)
ORDER BY id DESC
limit 60

Проблема в том, что это занимает около 8 секунд.

`chat` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `from` int(11) UNSIGNED NOT NULL,
  `to` int(11) UNSIGNED NOT NULL,
  `message` text NOT NULL,
  `sent` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `recd` tinyint(1) NOT NULL DEFAULT '0',
  `del_from_status` tinyint(1) NOT NULL DEFAULT '0',
  `del_to_status` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `from` (`from`),
  KEY `to` (`to`),
  FOREIGN KEY (`from`) REFERENCES cadastro (`id`),
  FOREIGN KEY (`to`) REFERENCES cadastro (`id`)
)

enter image description here

есть ли какие-либо идеи по индексированию или переписыванию этого выбора для повышения скорости?

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

Я предполагаю, что chat.id проиндексирован.Если нет, конечно, вы должны добавить индекс.

Если он проиндексирован, MySQL часто работает очень медленно с подвыборками.

Одна вещь, которую вы можете сделать, это преобразовать ваш подчиненный элемент во временную таблицу и присоединиться к ней.

Это будет выглядеть примерно так:

    CREATE TEMPORARY TABLE IF NOT EXISTS max_chat_ids
                ( INDEX(id) ) 
                ENGINE=MEMORY
                AS ( 'SELECT MAX(id) as id FROM chat
  WHERE (`to` = 1 and `del_to_status` = '0') or (`from` = 1 and `del_from_status` = '0')
  GROUP BY CASE WHEN 1 = `to` THEN `from` ELSE `to` END' );

, тогда вам нужно просто присоединиться к временной таблице:

SELECT c.id, c.from, c.to, c.sent, c.message, c.recd FROM chat c 
join max_chat_ids d on c.id=d.id
ORDER BY c.id DESC
limit 60

временные таблицы только живут в течение временисессии, поэтому, если вы проверите это в phpmyadmin, не забудьте выполнить оба запроса вместе с ';'между ними.

Если вы попробуете это, поделитесь своим результатом.

0 голосов
/ 11 июня 2018

Я предполагаю, что столбец id уже проиндексирован, поскольку он, вероятно, является первичным ключом таблицы.Если это не так, добавьте индекс:

create index ix1_chat on chat (id);

Затем, если селективность подзапроса хорошая, индекс поможет.Селективность - это процент строк, которые select читает по сравнению с общим числом строк.Это 50%, 5%, 0,5%?Если это 5% или меньше, то поможет следующий индекс:

create index ix2_chat on chat (`to`, del_to_status, `from`, del_from_status);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...