Я действительно смущен этими двумя запросами, они имеют нестабильную скорость запроса. Вот моя схема с двумя таблицами;
Таблица сообщений: (идентификатор, заголовок, дата и т. Д.) [Индекс даты]
Таблица отношений: (news_id, Relationship_id) [индексы есть для обеих строк и каждой строки]
Запрос A:
SELECT *
FROM posts
WHERE id IN (
SELECT news_id
FROM relationships
WHERE relation_id IN (?)
)
AND status = 1
ORDER BY `date` DESC
Запрос Б:
SELECT *
FROM posts AS p
INNER JOIN relationships AS r ON r.news_id = n.id
WHERE r.relation_id IN (?)
AND n.status = 1
ORDER BY n.date DESC
Теперь странная часть - это результаты тестов; сначала пытаемся использовать Relationship_id из 30 строк;
Запрос A: всего 30, запрос занял 5,56 секунды.
Запрос B: всего 30, запрос занял 0,03 секунды
A медленнее на меньшем количестве строк, B - скорость на меньшем количестве строк. Затем пытаемся использовать Relationship_id, имеющую 3k строк;
Запрос A: всего 3850, запрос занял 0,05 секунды.
Запрос B: всего 3850, запрос занял 0,70 секунды.
Так что меня это смутило, с большим количеством данных теперь A работает быстрее. И, наконец, попытка multi Relations_id с + 10k строками; пример; relation_id IN (1, 2, 3, 4)
Запрос A: всего 18 906, запрос занял 0,01 сек.
Запрос B: всего 18 906, запрос занял 3,34 секунды.
Так что я должен делать? Запрос A - это скорость для такого большого количества строк, но медленная с меньшим количеством строк. Есть ли еще одно верное предложение для этого запроса? (извините за плохой английский или грамматические ошибки)
ИЗМЕНИТЬ
Вот SQL EXPLAIN s;
Запрос A с 30 строками
Запрос B с 30 строками
Запрос A с 18k строками
Запрос B с 18k строками
1 ответ
Очень странно, но это MySQL ;-)
Оптимизатор считает, что status = 1
является сильным ограничением. Если это так, вы получите
select status=1, count(*) as num from posts group by status=1
Если только небольшая часть вашей таблицы содержит status=1
, тогда решение с 30 строками все еще неплохо с точки зрения mysqls.
Если большая часть имеет status = 1
, вам следует попробовать запрос с
from posts ignore index (status) ...
Или
from posts force index (id) ...
Чтобы обеспечить соблюдение правила "где-в-решении".
Более подробную информацию вы можете получить через
explain select count(*) from relationships where relation_id in (1)
Это показывает, какой размер ожидает оптимизатор на основе статистики индекса.
Проблема с фиксированными индексными подсказками в том, что они исправлены. Это означает, что они подходят как для хороших, так и для плохих сценариев.
Иногда временная таблица помогает избежать этого, вы можете сохранить в ней соответствующие отношения.
Похожие вопросы
Новые вопросы
mysql
MySQL — это бесплатная система управления реляционными базами данных (RDBMS) с открытым исходным кодом, которая использует язык структурированных запросов (SQL). НЕ ИСПОЛЬЗУЙТЕ этот тег для других БД, таких как SQL Server, SQLite и т. д. Это разные БД, которые используют свои собственные диалекты SQL для управления данными.
where in
не должен занимать 5 секунд. Вы уверены, что никакие другие вопросы не мешают измерениям? Это повторяется?posts.id
указатель?