приводится таблица MySQL содержит следующие две таблицы таблицы (упрощенный):использованием диапазона с композитным ключом
(~13000) (~7000000 rows)
--------------- --------------------
| packages | | packages_prices |
--------------- --------------------
| id (int) |<- ->| package_id (int) |
| state (int) | | variant_id (int) |
- - - - - - - | for_date (date) |
| price (float) |
- - - - - - - - -
Каждая комбинация package_id
/for_date
только несколько (в среднем 3) варианты. И state
- 0 (неактивный) или 1 (активный). Около 4000 из 13000 активных.
Сначала я просто хочу знать, какие пакеты имеет ценовой набор (независимо от изменения), поэтому я добавляю составной ключ, охватывающий (1) for_date
и (2) pid
и я запрос:
select distinct package_id from packages_prices where for_date > date(now())
Этих запрос занимает 1 секунду, чтобы вернуть 3500 строк, что слишком много. Объяснение говорит мне, что составной ключ используется с key_len 3, а 2000000 строк проверяются с фильтром 100% с типом. Using where; Using index; Using temporary
. Различный возвращает его к 3500 рядам.
Если я вывожу distinct
, то больше не упоминается Using temporary
, но затем запрос возвращает 1000000 строк и занимает 1 секунду.
вопрос 1: почему этот запрос настолько медленный и как я могу ускорить его, не добавляя или не изменяя столбцы в таблице? Я ожидал бы, что, учитывая составной ключ, этот запрос должен стоить менее 0,01.
Теперь я хочу знать, какие активные пакеты, у которых есть цена.
Поэтому я добавляю ключ на state
и добавляю новый составной ключ, как и выше, но в обратном порядке. И я пишу свой запрос следующим образом:
select distinct packages.id from packages
inner join packages_prices on id = package_id and for_date > date(now())
where state = 1
Запрос сейчас занимает 2 секунды. Объяснение говорит мне, что для таблицы packages
ключ на state
используется с key_len 4, исследует 4000 строк и фильтрует 100% тип типа ref. Using index; Using temporary
. А для таблицы packages_prices
новый составной ключ используется с key_len 4, рассматривается 1000 строк и фильтров 33.33% с типом ref. Using where; Using index; Distinct
. Четкость возвращает его к 3000 рядам.
Если я вывожу distinct
, Using temporary
и Distinct
больше не упоминаются, а запрос возвращает 850000 строк и занимает 3 секунды.
вопрос 2: Почему запрос намного медленнее сейчас? Почему диапазон больше не используется в соответствии с Объяснением? И почему фильтрация с новым составным ключом снизилась до 33,33%? Я ожидал, что составной ключ снова будет фильтровать 100% -ный экземпляр.
Все это кажется очень простым и тривиальным, но это стоило мне часов и часов, и я до сих пор не понимаю, что происходит на самом деле под капотом.
Прежде всего, вы должны, вероятно, задать два отдельных вопроса. Затем, пожалуйста, укажите таблицу создания, создайте индекс и покажите нам полный план объяснения. –
, когда вы сказали «варианты», вы имеете в виду разные 'packages_prices'? –
@HoneyBadger Это две разделенные таблицы. Но он поставил его бок о бок. –