Оптимизировать SQL-запрос

У меня проблема с оптимизацией этого запроса:

SET @SEARCH = "dokumentalne";

SELECT SQL_NO_CACHE
`AA`.`version` AS `Version` , 
`AA`.`contents` AS `Contents` , 
`AA`.`idarticle` AS `AdressInSQL` , 
`AA` .`topic` AS `Topic` ,
MATCH (`AA`.`topic` , `AA`.`contents`) AGAINST (@SEARCH) AS `Relevance` , 
`IA`.`url` AS `URL`
FROM `xv_article` AS `AA`
INNER JOIN `xv_articleindex` AS `IA` ON ( `AA`.`idarticle` = `IA`.`adressinsql` )
INNER JOIN (
    SELECT `idarticle` , MAX( `version` ) AS `version`
    FROM `xv_article`
    WHERE MATCH (`topic` , `contents`) AGAINST (@SEARCH)
    GROUP BY `idarticle`
) AS `MG`
ON ( `AA`.`idarticle` = `MG`.`idarticle` ) 
WHERE `IA`.`accepted` = "yes"
AND `AA`.`version` = `MG`.`version`
ORDER BY `Relevance` DESC
LIMIT 0 , 30

Теперь этот запрос использует ^ 20 секунд. Как это оптимизировать?

ОБЪЯСНЕНИЕ дает это:

1  PRIMARY  AA  ALL  NULL  NULL  NULL  NULL  11169  Using temporary; Using filesort
1  PRIMARY    ALL  NULL  NULL  NULL  NULL  681  Using where
1  PRIMARY  IA  ALL  accepted  NULL  NULL  NULL  11967  Using where
2  DERIVED  xv_article  fulltext  topic  topic  0     1  Using where; Using temporary; Using filesort

Это пример сервера с моими данными:

user: bordeux_4prog
password: 4prog
phpmyadmin: http://phpmyadmin.bordeux.net/
chive: http://chive.bordeux.net/

person bordeux    schedule 15.01.2011    source источник
comment
Вы действительно хотите, чтобы эти подробности были опубликованы в Интернете для всеобщего обозрения?   -  person John Parker    schedule 15.01.2011
comment
+1 за настройку тестового сервера для SO Crowd   -  person too    schedule 15.01.2011
comment
Вы знаете, что использование `backtags` необходимо только тогда, когда вы хотите использовать оператор MySQL в качестве переменной или таблицы или что-то в этом роде (например, `order`)? Ввод всего с помощью `s выглядит очень раздражающим imho.   -  person Alec    schedule 15.01.2011
comment
Внутренний запрос с предложением group by, вероятно, довольно дорог. Можете ли вы объяснить, что вы пытаетесь сделать? Кроме того, пожалуйста, измените пароль вашего сервера.   -  person O. Jones    schedule 15.01.2011
comment
эти данные находятся на открытой лицензии ;D   -  person bordeux    schedule 16.01.2011


Ответы (2)


Похоже, ваша БД мертва. Избавление от внутреннего запроса является ключевой частью оптимизации. Пожалуйста, попробуйте этот (не проверенный) запрос:

SET @SEARCH = "dokumentalne";

SELECT SQL_NO_CACHE
  aa.idarticle AS `AdressInSQL`,
  aa.contents AS `Contents`,
  aa.topic AS `Topic`,
  MATCH(aa.topic , aa.contents) AGAINST (@SEARCH) AS `Relevance`,
  ia.url AS `URL`,
  MAX(aa.version) AS `Version`
FROM
  xv_article AS aa,
  xv_articleindex AS ia
WHERE
  aa.idarticle = ia.adressinsql
  AND ia.accepted = "yes"
  AND MATCH(aa.topic , aa.contents) AGAINST (@SEARCH)
GROUP BY
  aa.idarticle,
  aa.contents,
  `Relevance`,
  ia.url
ORDER BY
  `Relevance` DESC
LIMIT
  0, 30

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

SELECT SQL_NO_CACHE
  iq.idarticle AS `AdressInSQL`,
  iq.topic AS `Topic`,
  iq.contents AS `Contents`,
  iq.url AS `URL`,
  MATCH(iq.topic, iq.contents) AGAINST (@SEARCH) AS `Relevance`
FROM (
   SELECT
     a.idarticle,
     a.topic,
     a.contents,
     i.url,
     MAX(a.version) AS version
   FROM
     xv_article AS a,
     xv_articleindex AS i
   WHERE
     i.accepted = "yes"
     AND a.idarticle = i.adressinsql
   GROUP BY
     a.idarticle AS id,
     a.topic,
     a.contents,
     i.url
) AS iq
WHERE
  MATCH(iq.topic, iq.contents) AGAINST (@SEARCH)
ORDER BY
  `Relevance` DESC
LIMIT
  0, 30
person too    schedule 15.01.2011

Первое, что я заметил в вашей БД, это то, что у вас нет индекса для xv_articleindex.adressinsql. Добавьте его, и это должно значительно повысить производительность запросов. Кроме того, одна таблица — MyISAM, а другая — InnoDb. Используйте один движок (в общем, я бы рекомендовал InnoDB)

person a1ex07    schedule 15.01.2011
comment
я не могу использовать innodb, потому что InnoDB не имеет модуля полнотекстового поиска. - person bordeux; 16.01.2011