На локальном хосте запрос работал нормально, но на нашем сервере он очень медленный - PullRequest
1 голос
/ 06 марта 2011

Мы протестировали по 1 миллиону записей в каждой таблице, результаты были хорошими, всегда ниже 0,08.Таким образом, мы внедрили на нашем сервере, но это очень медленно там, занимает до 36 секунд.

Мы попросили помощи, прежде чем оптимизировать запрос, который мы выполняли на нашей тестовой машине, мы подробно описали базовую структуру нашегоотношение один ко многим: Проблемы с оптимизацией структуры больших запросов и таблиц

Это последний запрос, который мы используем после получения справки по ссылке выше:

explain 
SELECT
    st.sid, st.title, st.summary, st.storynotes, st.thumb, st.completed, st.wordcount, st.rid, st.date, st.updated,
    stats.total_reviews, stats.total_recommendations,
    (SELECT GROUP_CONCAT(CAST(catid AS CHAR)) FROM fanfiction_stories_categories WHERE sid = st.sid) as categories,
    (SELECT GROUP_CONCAT(CAST(genre_id AS CHAR)) FROM fanfiction_stories_genres WHERE sid = st.sid) as genres,
    (SELECT GROUP_CONCAT(CAST(warning_id AS CHAR)) FROM fanfiction_stories_warnings WHERE sid = st.sid) as warnings
    FROM
    fanfiction_stories st
    LEFT JOIN fanfiction_stories_stats stats ON st.sid = stats.sid
    JOIN fanfiction_stories_categories cat ON st.sid = cat.sid AND cat.catid = 924
    WHERE validated = 1
    ORDER BY updated DESC
    LIMIT 0, 15

Это объяснение:

http://dl.dropbox.com/u/14508898/Printscreen/stackoverflow_explain_print_003.PNG

0 строк затронуто, найдено 6 строк.Длительность 1 запроса: 31 356 сек.

Обновлено
Мы удалили некоторые старые индексы предыдущей структуры БД, которые были в fanfiction_stories, и добавили новые индексы в fanfiction_stories_categories, теперь намного быстрееВот обновленное объяснение:

http://dl.dropbox.com/u/14508898/Printscreen/stackoverflow_explain_print_004.PNG

Извините, программа, которую я использую, только форматирует таблицу объяснения как HTML, CSV и т. Д., Не создает таблицу ASCII для отображения здесь.

Можем ли мы оптимизировать его еще больше?Любая помощь очень ценится.

Ответы [ 2 ]

0 голосов
/ 07 марта 2011

Это должно работать, хотя у меня нет структур таблиц и примеров данных для моделирования.Удаляя каждый из (SELECT ...) как столбец и просто оставляя как левые соединения, группировка всего внешнего запроса по sid должна дать тот же результат.Я думаю, что он более эффективен, чем каждый подзапрос AS Column, чем обычный запрос / соединение.Group_Concat в любом случае группируется на основе "sid" в конце и должна сохранять ... Единственное, что может быть проблемой, - это любые значения NULL в конце в этих полях concat, которые затем можно обернуть с помощью теста IFNULL ().

Я бы гарантировал, что КАЖДЫЙ из этих таблиц имеет индекс для "sid", используемого для объединения.Кроме того, в вашей основной таблице историй должен быть индекс Validated для его критериев = 1.

На основе ваших отзывов я бы переместил критерии и первую таблицу в начало по категориям. Сначала получите ОДНУ КАТЕГОРИЮ, затемпосмотрите, какие истории связаны с этим.Затем, только из этих историй, подключите остальную часть жанра, предупреждения, комментарии и т. Д. У вас, очевидно, есть меньший набор категорий, поэтому я бы выбрал THAT в качестве основной таблицы в запросе.Дайте мне знать, как это работает.

SELECT STRAIGHT_JOIN
      st.sid, 
      st.title, 
      st.summary, 
      st.storynotes, 
      st.thumb, 
      st.completed, 
      st.wordcount, 
      st.rid, 
      st.date, 
      st.updated,
      stats.total_reviews, 
      stats.total_recommendations,
      GROUP_CONCAT( DISTINCT cat.catid ) categories,
      GROUP_CONCAT( DISTINCT genre.genre_id ) genres,
      GROUP_CONCAT( DISTINCT warn.warning_id ) as warnings
   FROM
      fanfiction_stories_categories cat
         JOIN fanfiction_stories st
            ON cat.sid = st.sid
            AND st.Validated = 1
            LEFT JOIN fanfiction_stories_stats stats 
               ON st.sid = stats.sid
            LEFT JOIN fanfiction_stories_genres genre
               on st.sid = genre.sid
            LEFT JOIN fanfiction_stories_warnings warn
               on st.sid = warn.sid
   WHERE 
      cat.catid = 924
   group by 
      st.sid
   ORDER BY 
      updated DESC
   LIMIT 
      0, 15
0 голосов
/ 06 марта 2011

Привет! Вместо JOIN лучше использовать явное INNER JOIN, например:

Это также могут быть все GROUP_CONCAT, которые вы делаете, они очень жадны до памяти.

SELECT
    st.sid, st.title, st.summary, st.storynotes, st.thumb, st.completed, st.wordcount, st.rid, st.date, st.updated,
    stats.total_reviews, stats.total_recommendations,
    (SELECT GROUP_CONCAT(CAST(catid AS CHAR)) FROM fanfiction_stories_categories WHERE sid = st.sid) as categories,
    (SELECT GROUP_CONCAT(CAST(genre_id AS CHAR)) FROM fanfiction_stories_genres WHERE sid = st.sid) as genres,
    (SELECT GROUP_CONCAT(CAST(warning_id AS CHAR)) FROM fanfiction_stories_warnings WHERE sid = st.sid) as warnings
    FROM
    fanfiction_stories st
    LEFT JOIN fanfiction_stories_stats stats ON st.sid = stats.sid
    INNER JOIN fanfiction_stories_categories cat ON st.sid = cat.sid AND cat.catid = 924
    WHERE validated = 1
    ORDER BY updated DESC
    LIMIT 0, 15
...