У меня есть опыт медленных запросов к базе данных MySQL.
База данных выглядит просто как слова, чем набор слов и связанных вещей, таких как изображения, записи, предложения к словам.
Заявление Bluehost У меня огромные накладные расходы и медленные запросы, и мне нужно оптимизировать их.
Какие могут быть решения для оптимизации базы данных! Список типичных шагов, чтобы проверить для каждой таблицы (отношения) или интенсивно используемых запросов, чтобы улучшить это?
Примеры запросов, найденных в tmp / logs
SELECT transcription FROM english_details WHERE translation_id = '2216'
SELECT recording FROM word_recordings_de WHERE translation_id = '3342'
SELECT english_sentences.sentence_id, english_sentences.sentence_eng,
english_sentences.sentence_pl,english_sent_recordings.recording
FROM english_sentences LEFT JOIN english_sent_recordings USING (sentence_id)
WHERE english_sentences.translation_id = '2239'
SELECT post_it FROM post_it WHERE user_id = '' AND translation_id = 10562 LIMIT 1
Я считаю, это проблема с базой данных, запросами или двумя многими пользователями. Является ли число 480 000 сеансов (Google Analytics) в месяц для общего хостинга Bluehost большим?
ОБНОВИТЬ
Считаете ли вы, что важная операция загрузки слов для заданного набора слов, используя это:
$arWordIds = $this->getWordsIds();
foreach($arWordIds as $wordId) {
switch($this->wordset_type) {
case WordSet::TYPE_BASIC:
$col->addItem(new Word($this->dbc, $wordId), $wordId);
break;
case WordSet::TYPE_DETAILED:
$col->addItem(new WordDetails($this->dbc, $wordId), $wordId);
break;
}
}
Может быть проблема? Как существует один запрос для идентификаторов слов, а затем запросы для каждого слова для данного идентификатора (возможно, несколько запросов независимо для предложений, записей и т. Д.)? Может быть, лучше сделать один больший запрос, например, для всех слов данных, например, WHERE translation_id IN (id1, id2, id3, …), с множеством объединений, возвращающих данные для 100 слов за один прогон?
Но чем я могу заполнить объекты Word вручную? поскольку у меня есть эти объекты Word в PHP как некоторые объекты DAO, которые загружают данные для данного Word с предоставленным идентификатором. Тогда это программирование будет лучше подходить для некоторого процедурного программирования, чем объектно-ориентированное, я думаю. Пока я загружаю все данные в одном запросе (слово, предложения, комментарии)? Можно ли даже загрузить в одном запросе слова для множества идентификаторов и для каждого слова множество связанных предложений? или изображения?
ОБНОВЛЕНИЕ 2
У меня есть индексы, уникальные и т. Д. Во многих местах, и в некоторых из них я добавил их. Первичные ключи есть везде. Индексы, которые я добавил, когда атрибуты используются в предложении WHERE. Конечно, могут быть некоторые не хватает индекса, если я забыл добавить его.
Я выполняю ** EXPLAIN SELECT … ** и пытаюсь достичь типа доступа, отличного от ALL, как const, ref, eq_ref или system.
Пример таблицы: (я предполагаю, что> 50-100 таблиц в базе данных)
CREATE TABLE `post_it` (
`post_it` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`translation_id` int(10) unsigned NOT NULL,
`text` tinytext NOT NULL,
`lang` varchar(5) NOT NULL DEFAULT 'plen',
PRIMARY KEY (`post_it`),
KEY `user_id` (`user_id`,`translation_id`)
) ENGINE=MyISAM AUTO_INCREMENT=235 DEFAULT CHARSET=utf8
Я также заменил конструкцию объекта Word. До сих пор свойства Word, где лениво загружается каждое при доступе. Таким образом, это было в цикле (например, 100 слов в списке), а затем распечатка в XML каждого свойства заставила 5-10 запросов получить собственное слово, иностранное слово, транскрипцию и т. Д.
Нет, я добавил в конструктор Word готовую предварительную загрузку всех свойств, которые 1to1, и только свойства 1toN, которые я оставил лениво загруженными. Теперь я рассматриваю, будет ли такой запрос лучше нескольких простых без объединения:
SELECT nt.french_id, nt.article, n.french_word, ft.english_id, '-' AS 'english_article', en.english_word, p.part,
ed.transcription, ed.definition, r.recording
FROM translation ft
INNER JOIN translation_enfr nt ON nt.translation_id = ft.translation_id
INNER JOIN french n ON n.french_id = nt.french_id
INNER JOIN english en ON en.english_id = ft.english_id
INNER JOIN parts p ON p.part_id = ft.part_id
LEFT JOIN english_details ed ON ed.translation_id = ft.translation_id
LEFT JOIN word_recordings r ON r.translation_id = ft.translation_id
WHERE ft.translation_id = 3
Задача ещё не решена.
Других решений пока нет …