MySQL Slow join - но не всегда и не на всех таблицах - PullRequest
1 голос
/ 23 июня 2010

Мы столкнулись с проблемой производительности базы данных MySQL, которая настолько странна, что нам нужен еще один взгляд, чтобы сказать нам, сходим ли мы с ума или нет.В нашей команде 2 сертифицированных разработчика MySQL, но все, что они могут сказать: «это невозможно».

В любом случае, вот такая ситуация: у нас есть запрос, который теоретически должен быть достаточно быстрым, нона самом деле это медленно.Если мы сократим запрос, удалив 1 объединение, запрос станет чрезвычайно быстрым.Если мы удалим другое соединение, оно все равно будет очень медленным, хотя объединенная таблица имеет почти такую ​​же структуру.Хуже того: соединения ИНОГДА бывают быстрыми, иногда нет ... кажется, что это какая-то случайная проблема, хотя это не имеет никакого отношения к загрузке сервера, поскольку у меня она тоже есть в локальной системе.

Структура таблицы выглядит следующим образом:

Table : article Rows : 57491
Field            Type                 Null   Key     Default     Extra
arti_id          int(10) unsigned     NO     PRI                 auto_increment
prev_id          int(10) unsigned     YES    MUL                 (null)
news_id          int(10) unsigned     NO     MUL                 (null)
cate_id          int(10) unsigned     NO     MUL                 (null)
pdf_id           int(10) unsigned     YES    MUL                 (null)
imag_id          int(10) unsigned     YES    MUL                 (null)
publication_date date                 NO     MUL                 (null)
title            varchar(255)         NO     MUL                 (null)
full_text        text                 YES    (null)              (null)

Table : category Rows : 3
Field            Type                 Null   Key     Default     Extra
cate_id          int(10) unsigned     NO     PRI                 auto_increment
code             varchar(7)           NO     (null)              (null)

Table : language Rows : 4
Field            Type                 Null     Key     Default     Extra
lang_id          int(10) unsigned     NO       PRI                 auto_increment
code             varchar(2)           NO       (null)              (null)

Table : newspaper Rows : 393
Field            Type                 Null     Key     Default     Extra
news_id          int(10) unsigned     NO       PRI                 auto_increment
lang_id          int(10) unsigned     NO       MUL                 (null)
name             varchar(255)         NO       UNI                 (null)

Теперь начинается странная часть: как вы можете видеть, 046_newspaper и 046_category имеют первичный ключ (к счастью).На оба они ссылаются из a046_article по внешнему ключу.Когда мы запускаем следующий запрос:

SELECT SQL_NO_CACHE
    article.*
FROM
    article
        INNER JOIN
        newspaper AS `n`
        ON
        article.news_id = n.news_id
ORDER BY
    article.publication_date DESC
LIMIT
    50

Мы получаем результат через 0,016 секунды, что довольно быстро.

Теперь, когда мы заменяем объединение газетой объединением с категорией:

SELECT SQL_NO_CACHE
    article.*
FROM
    article
        INNER JOIN
        category AS `c`
        ON
        article.cate_id = c.cate_id
ORDER BY
    article.publication_date DESC
LIMIT
    50

Запрос занимает 1,02 секунды.

Странно то, что это не всегда так.Иногда, без видимой причины, первый запрос тоже занимает примерно столько же времени.

В конце мы хотим сделать следующее:

SELECT SQL_CALC_FOUND_ROWS
    *,
    `n`.`name` AS `news_name`,
    `c`.`cate_id`,
    `c`.`code` AS `cate_name`,
    `l`.`code` AS `lang_name`
FROM
    `article`
        INNER JOIN
        `newspaper` AS `n`
        ON
        article.news_id = n.news_id
            INNER JOIN
            `category` AS `c`
            ON
            article.cate_id = c.cate_id
                INNER JOIN
                `language` AS `l`
                ON
                n.lang_id = l.lang_id
ORDER BY
    `article`.`publication_date` DESC
LIMIT
  50

, что на этом этапе занимает более 12 секунд.Отчасти это связано с *, который мы могли бы заменить отдельными полями, но тогда это все равно занимает 3 секунды.

Мы попробовали несколько вещей: - Добавление индексов (хотя все необходимые индексы уже были там)и добавление большего количества - просто плохая идея) - Увеличение размера буфера сортировки и буфера ключей - Глядя на многое объяснить - - Снова и снова читать руководство по MySQL - Чтение множества форумов Однако ничего подобного не решиловыпуск.

Если у кого-то есть идеи, смело кричите!Если вам нужен SQL-скрипт или даже доступ к базе данных, чтобы вы могли попробовать, дайте мне знать ... наш клиент много жалуется на медленные страницы ...

Спасибо!

Ответы [ 3 ]

0 голосов
/ 07 июля 2010

Я бы сделал таблицу SHOW INDEX ON для всех таблиц и проверил бы, правильно ли выглядит столбец мощности (т. Е. Нет NULL).Или вы можете просто сделать анализ на каждом столе для хорошей меры.Поскольку у вас там есть 2 сертифицированных разработчика MySQL, вы, вероятно, уже сделали это.

Следующий шаг - посмотреть на EXPLAIN и посмотреть, как MySQL оптимизирует его.Возможно, вам придется использовать FORCE, USE или IGNORE, чтобы правильно оптимизировать его.Скорость будет зависеть от MySQL и ОС с данными кеша (т.е. индексами), но не с запросом, когда вы укажете «no cache».Вы можете опубликовать объяснение?

0 голосов
/ 09 июля 2010

Я думаю, вы можете попробовать с помощью скалярного запроса.

0 голосов
/ 07 июля 2010
  1. Всегда используйте EXPLAIN (QUERY) для профилирования и понимания того, как MySQL анализирует ваши запросы.
  2. Проверьте ваши ИНДЕКСЫ, MySQL активно выбирает неправильные индексы для выбора.
  3. Попробуйте использовать подсказки SELECT и INDEX. http://dev.mysql.com/doc/refman/5.1/en/index-hints.html.

    SELECT * FROM table1 ИНДЕКС ИСПОЛЬЗОВАНИЯ (col1_index, col2_index) ГДЕ col1 = 1 И col2 = 2 И col3 = 3;

    SELECT * FROM table1 IGNORE INDEX (col3_index) ГДЕ col1 = 1 И col2 = 2 И col3 = 3;

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