2015-04-02 9 views
0

У меня возникает странная проблема, когда этот конкретный запрос MySQL будет работать почти в 50 раз медленнее после того, как мы обновили нашу базу данных с MySQL 5.1.73 до 5.6.23.Тот же запрос MySQL работает намного медленнее в 5.6, чем в 5.1

Это SQL-запрос:

SELECT `companies`.* 
FROM `companies` 
    LEFT OUTER JOIN `company_texts` 
       ON `company_texts`.`company_id` = `companies`.`id` 
        AND `company_texts`.`language` = 'en' 
        AND `company_texts`.`region` = 'US' 
    INNER JOIN show_texts 
      ON show_texts.company_id = companies.id 
       AND `show_texts`.`is_deleted` = 0 
       AND `show_texts`.`language` = 'en' 
       AND `show_texts`.`region` = 'US' 
    INNER JOIN show_region_counts 
      ON show_region_counts.show_id = show_texts.show_id 
       AND show_region_counts.region = 'US' 
    WHERE ((`companies`.`id` NOT IN ('77', '26')) 
    AND (`company_texts`.is_deleted = 0) 
    AND `companies`.id IN (
     SELECT DISTINCT show_texts.company_id AS 
           id 
       FROM shows 
         INNER JOIN `show_rollups` 
           ON 
           `show_rollups`.`show_id` = `shows`.`id` 
            AND (`show_rollups`.`device_id` = 3) 
            AND (`show_rollups`.`package_group_id` = 2) 
            AND (`show_rollups`.`videos_count` > 0) 
           LEFT OUTER JOIN `show_texts` ON 
            `show_texts`.`show_id` = `shows`.`id` 
             AND 
            `show_texts`.`is_deleted` = 0 
             AND 
            `show_texts`.`language` = 'en' 
             AND 
            `show_texts`.`region` = 'US' 
             AND 
            shows.is_browseable = 1 
            AND 
            show_texts.show_id IS NOT NULL 
            AND ( 
             `show_rollups`.`episodes_count` > 0 
             OR `show_rollups`.`clips_count` > 0 
             OR `show_rollups`.`games_count` > 0 
             ) 


    )) 
    GROUP BY companies.id 
    ORDER BY Sum(show_region_counts.view_count) DESC 
    LIMIT 30 offset 30; 

Теперь проблема, когда я запускаю этот запрос в MySQL 5.1.73 перед обновлением, запрос будет только займет около 1,5 секунды, но после обновления до 5.6 .23, теперь он может подняться до 1 минуты.

Так что я сделал EXPLAIN этого запроса в 5.1.73, и я увидел это:

EXPLAIN with MySQL 5.1.73 Увеличенная версия: http://i.stack.imgur.com/c4ko0.jpg

И когда я объясняю в 5.6.23, я увидел это:

EXPLAIN with MySQL 5.6.23 Увеличенная версия: http://i.stack.imgur.com/CgBtA.jpg

Я могу видеть, что в обоих случаях есть полное сканирование (введите ALL) Т.Г. e показывает таблицу, но есть ли что-то еще, что я не вижу, что вызывает массовое замедление в 5.6?

Благодаря IS

+0

Я не могу прочитать эти планы объяснения - вы бы вставляли их в виде моноширинного текста? – halfer

+0

Пожалуйста, напишите отчет об ошибке на http: bugs.mysql.com; они хотят знать о случаях, когда новый оптимизатор хуже, чем старый. –

+0

от маленького я могу разобраться, что второй план объяснения выглядит лучше, чем первый –

ответ

0

Просьба указать SHOW CREATE TABLE. Без этого, я думаю, что вам не хватает этого желаемый индекс:

show_rollups: INDEX (device_id, package_group_id, videos_count)

У вас есть LEFT OUTER JOIN show_texts ... ON ... show_texts.show_id IS NOT NULL. Это, вероятно, неправильно по двум причинам: (а) Не используйте LEFT если вы не ищете NULL, и (б) тест NULL должен быть в отсутствующей WHERE пункта, а не в пункте ON.

Избавление от IN (SELECT ...)может помощью его передачи на обеих машинах:

SELECT c.* 
    FROM 
     (SELECT DISTINCT st.company_id AS id 
      FROM shows 
      INNER JOIN `show_rollups` AS sr ON sr.`show_id` = `shows`.`id` 
       AND (sr.`device_id` = 3) 
       AND (sr.`package_group_id` = 2) 
       AND (sr.`videos_count` > 0) 
      LEFT OUTER JOIN `show_texts` AS st ON st.`show_id` = `shows`.`id` 
       AND st.`is_deleted` = 0 
       AND st.`language` = 'en' 
       AND st.`region` = 'US' 
       AND shows.is_browseable = 1 
       AND st.show_id IS NOT NULL 
       AND (sr.`episodes_count` > 0 
         OR sr.`clips_count` > 0 
         OR sr.`games_count` > 0) 
    ) AS x 
    JOIN `companies` AS c ON x.id = c.id 
    LEFT OUTER JOIN `company_texts` AS ct ON ct.`company_id` = c.`id` 
      AND ct.`language` = 'en' 
      AND ct.`region` = 'US' 
    INNER JOIN show_texts AS st ON st.company_id = c.id 
      AND st.`is_deleted` = 0 
      AND st.`language` = 'en' 
      AND st.`region` = 'US' 
    INNER JOIN show_region_counts AS src ON src.show_id = st.show_id 
      AND src.region = 'US' 
    WHERE (c.`id` NOT IN ('77', '26')) 
     AND (ct.is_deleted = 0) 
    GROUP BY c.id 
    ORDER BY Sum(src.view_count) DESC 
    LIMIT 30 offset 30; 

Существует некоторая вероятность того, что для соединений будет связываться с вычислением в Sum(src.view_count).

+0

Привет, Рик, спасибо за ответ. Что касается SHOW CREATE TABLE, если я проверю это на show_rollups, есть один уникальный индекс в этих столбцах: show_id, 'package_group_id' и' device_id', а не для device_id, package_group_id и videos_count. Существует также первичный ключ для столбца id, и никакие другие индексы – user1805458

+0

Спасибо Рик Джеймс, я сделал небольшую коррекцию в вашем SQL, и он отлично работает и быстро! – user1805458

0

Мне очень жаль, но я не могу разобрать EXPLAIN скрин-грейферов на моем экране.

Без этого я бы подумал, изменились ли схемы для таблиц вообще или изменились двигатели базы данных. В частности, companys.id, по-видимому, используется в качестве первичного ключа.

+0

Извините, что фотографии выглядят небольшими, но если вы переходите к прямым ссылкам здесь, они более ясны: 5.1: i.stack.imgur. com/c4ko0.jpg 5.6: i.stack.imgur.com/CgBtA.jpg – user1805458