Я использую инфраструктуру Grails для проекта, который использует Hibernate для ORM. Grails поддерживает именованные запросы, которые переводятся в критерии гибернации. Я использовал P6Spy и SQLProfiler, чтобы попытаться повысить производительность одного из этих именованных запросов.
Проблема в том, что когда я запускаю запрос без предложения order by, он выполняется примерно за 1200 секунд. Когда я добавляю заказ по предложению, он увеличивается до 15 секунд.
Вот (примерно), как выглядит запрос конечного результата:
Select
*
from
article
left outer join
feed_articles
on
article.id = feed_articles.article_id
where
(
feed_articles.feed_id = 1 or
feed_articles.feed_id = 43 or
feed_articles.feed_id = 67
)
order by
article.updated
limit
50
В случае, если кто-то из экспертов Grails читает, вот урезанная версия домена статьи:
static hasMany = [articleFeeds: ArticleFeed]
Date updated
static namedQueries = {
containedInFeeds { feedList ->
articleFeeds{
or{
feedList.each{ feed ->
eq("feed", feed)
}
}
}
}
}
Грааль Примечание
Я попробовал это как, добавив
orderBy("updated", "desc")
maxResults("50")
в домене и попытавшись
Article.containedInFeeds().listDistinct(max: 50, sort: "updated", order: "desc")
в контроллере, но результирующий SQL кажется одинаковым в любом случае.
Я попытался добавить индекс к таблице статей для обновленного поля, но это не привело к повышению производительности.
Таблица артикулов содержит примерно 190 000 наименований.
Я также выполнил объяснение по запросам (как я рекомендовал в сообщении в блоге) и заметил, что без заказа только в качестве дополнения указывается только «Использование где». При использовании упорядочены по «Использование где, Использование временного, Использование сортировки файлов» все перечислены.
Я предполагаю, что я не создал индекс должным образом, что экземпляр mysql нуждается в некоторой настройке или в обоих.
Редактировать
Дополнительная информация
Я искал в Интернете дополнительную информацию об индексации, особенно о том, когда используются объединения и сортировки по. Самое близкое описание, которое мне удалось найти, это: http://hackmysql.com/case5, но сайт говорит, что он больше не поддерживается, и я предполагаю, что эти методы устарели (по крайней мере, они не работали для меня) , Мне бы очень хотелось получить представление о том, как / почему вещи должны индексироваться, а не просто получить ответ.
Вот запрошенные определения таблиц и объяснение вывода.
Артикул Таблица
CREATE TABLE `mydb`.`article` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`version` bigint(20) NOT NULL,
`link` varchar(255) DEFAULT NULL,
`image_id` bigint(20) DEFAULT NULL,
`unique_id` varchar(255) DEFAULT NULL,
`author` varchar(255) DEFAULT NULL,
`title` varchar(255) DEFAULT NULL,
`source` varchar(255) DEFAULT NULL,
`updated` datetime DEFAULT NULL,
`description` varchar(1000) DEFAULT NULL,
`date_created` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `FK317B135BE74D38` (`image_id`),
KEY `Updated_Idx_Test` (`id`,`updated`) USING BTREE,
CONSTRAINT `FK317B135BE74D38` FOREIGN KEY (`image_id`) REFERENCES `remote_image` (`id`)
)
ENGINE=InnoDB AUTO_INCREMENT=195939 DEFAULT CHARSET=latin1;
_Feed_Articles table_
CREATE TABLE `mydb`.`feed_articles` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`version` bigint(20) NOT NULL,
`article_id` bigint(20) NOT NULL,
`feed_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `FK9E0121145D70E756` (`article_id`),
KEY `FK9E012114A51FD776` (`feed_id`),
CONSTRAINT `FK9E0121145D70E756` FOREIGN KEY (`article_id`) REFERENCES `article` (`id`),
CONSTRAINT `FK9E012114A51FD776` FOREIGN KEY (`feed_id`) REFERENCES `feed` (`id`)
)
ENGINE=InnoDB AUTO_INCREMENT=231684 DEFAULT CHARSET=latin1;
Объяснить вывод
Я немного изменил запрос, изменив предложение where для получения из 10 feed_id:
feed_articles.feed_id = 1 or
.
.
.
feed_articles.feed_id = 10
Выход:
+----+-------------+-----------+--------+---------------------------------------+--------------------+---------+----------------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+--------+---------------------------------------+--------------------+---------+----------------------------+-------+----------------------------------------------+
| 1 | SIMPLE | feed_item | range | FK9E0121145D70E756,FK9E012114A51FD776 | FK9E012114A51FD776 | 8 | NULL | 51909 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | item | eq_ref | PRIMARY,Updated_Idx_Test | PRIMARY | 8 | wiumidev.feed_item.item_id | 1 | |
+----+-------------+-----------+--------+---------------------------------------+--------------------+---------+----------------------------+-------+----------------------------------------------+
Спасибо за помощь.