Секционирование Mysql не работает на моем вложенном запросе

explain 
SELECT
    ip_src,
    (SELECT country FROM ip_location WHERE ip_start between (134744072-500000) and (134744072) and ip_end > 134744072) country_src,
    ip_dst
FROM
    event e
WHERE 
    long_date BETWEEN '2016-03-25 00:00:00' AND '2016-03-25 23:59:59'
LIMIT 1

раздел подрезая деятельность

explain
SELECT
    ip_src,
    (SELECT country FROM ip_location WHERE ip_start between (ip_src-500000) and (ip_src) and ip_end > ip_src) country_src,
    ip_dst
FROM
    event e
WHERE 
    long_date BETWEEN '2016-03-25 00:00:00' AND '2016-03-25 23:59:59'
LIMIT 1

раздел обрезки не работает

У меня есть 2 запроса,
значение ip_src-134744072.

Моя таблица Ip_location секционирована по столбцу range on ip_start.
Когда я запускаю первый запрос, его делают с разделом обрезки, но во втором запросе свой доступ ко всем разделам.

Кто-нибудь, пожалуйста, дайте мне ключ, я смотрю вокруг n не знаю еще, что происходит, спасибо, прежде чем 🙂

1 ответ

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

    Первый запрос ограничивает вложенный запрос определенным диапазоном ip_startмежду постоянными значениями 134744072-500000и134744072, поэтому ясно, в каком разделе находятся данные. (Кстати.: необходимо убедиться, что вложенный запрос возвращает max. одна строка, иначе это приведет к ошибке).

    Для второго запроса оптимизатор не может знать необходимый диапазон до его запуска. Это будет зависеть от данных, которые он находит при чтении eventтаблицы. Именно поэтому select_typeдля этого запросаdependent subquery, в то время как для первого запроса, это subquery(так фиксированный resultset независимо от eventтаблицы). Таким образом, оптимизатор не может исключить раздел, поэтому он будет перечислять их все. Когда запрос будет выполнен, он прочитает первую строку, теперь знает, что значение для ip_srcis134744072, и, следовательноip_start,- range и раздел, в котором находятся данные, и поэтому MySQL теперь будет искать его в правильном разделе.

    Оба запроса на самом деле будут читать только из этого одного раздела, но для первого MySQL знает, что прежде чем он начнет, для второго он не делает.

    И, наконец, предупреждение: похоже, вы пытаетесь использовать разделы для ускорения запроса. Это не то, что разделы используются для! Для этого используются индексы. Для limit 1, это не будет иметь значения, но если вы запросите больше строк, каждый раздел будет действовать как независимая таблица (которая в основном является), поэтому вместо того, чтобы искать данные в 1 индексе (большей таблицы, но размер в основном не имеет значения, когда у вас есть индекс), MySQL должен искать данные в 30, 40 различных разделах (=таблицы), все имеющие свои собственные индексы, файлы и структуры. Это, как правило, будет медленнее (и почти никогда быстрее), чем не использовать разделы. 600k строк уже может быть достаточно, чтобы увидеть, по крайней мере, небольшой эффект этого, поэтому сделайте тест без секционирования.