Мы столкнулись с проблемой производительности базы данных 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-скрипт или даже доступ к базе данных, чтобы вы могли попробовать, дайте мне знать ... наш клиент много жалуется на медленные страницы ...
Спасибо!