Порядок соединения django по причинам сортировки файлов
Я использую django для разработки своего веб-приложения. Недавно я обнаружил, что используя django ROM join
делает оптимизацию SQL очень трудно. Вопрос в том, что у меня есть новости и теги, они связаны многими со многими (мое приложение называется "новости").
class News(modeles):
title = models.CharField(max_length=128,verbose_name='title')
rank = models.IntegerField(verbose_name="ranking")
publish_time = models.DatetimeField()
class Tags(models):
tag_name= models.CharField(max_length=32,unique=True)
news = models.ManyToManyField(News)
и я хочу выбрать новости, чьи publish_time находятся между time1(2011-09-01) и time2(2016-05-10) и имеют определенный тег, а затем упорядочить их по -publish_time,-rank . поэтому я пишу запрос:
News.objects.filter(tags__tag_name='someTag').filter(publish_time__lte='2016-05-10',pulish_time__gte='2011-09-01').order_by('-publish_time','-rank')[0:9]
Django ORM поможет мне построить SQL ниже:
SELECT
`news_news`.`id`,
`news_news`.`title`,
`news_news`.`rank`,
`news_news`.`publish_time`,
FROM `news_news`
INNER JOIN `news_tags_news`
ON ( `news_news`.`id` = `news_tags_news`.`news_id` )
INNER JOIN `news_tags`
ON ( `news_tags_news`.`tags_id` = `news_tags`.`id` )
WHERE (
`news_tags`.`tag_name` = 'someTag'
AND `news_news`.`publish_time` >= '2011-09-01'
AND `news_news`.`publish_time` <= '2016-05-10'
)
ORDER BY `news_news`.`publish_time` DESC, `news_news`.`rank` DESC LIMIT 9;
Я должен был создать INDEX news_order_index ON NEWS('publish_time','rank'), когда объясняю raw sql, он говорит мне:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: news_tags
type: const
possible_keys: PRIMARY,tag_name
key: tag_name
key_len: 194
ref: const
rows: 1
Extra: Using index; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: news_tags_news
type: ref
possible_keys: tags_id,news_tags_news_news_id_index,news_tags_news__tags_id
key: tags_id
key_len: 4
ref: const
rows: 6232
Extra: Using index
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: news_news
type: eq_ref
possible_keys: PRIMARY,news_order_index
key: PRIMARY
key_len: 4
ref: news.news_tags_news.news_id
rows: 1
Extra: Using where
3 rows in set (0.00 sec)
используя filesort!!!, у меня есть много элементов в таблице, использование filesort делает запрос очень медленным. так что я бы хотел, чтобы django orm создал подзапрос, подзапрос упорядочил новости по -publish_time, -rank сначала и выполнил объединение позже, таким образом, я могу уничтожить сортировку файлов. необработанный sql, который я хочу, чтобы django ORM создал:
SELECT
`ordered_news_table`.`id`,
`ordered_news_table`.`title`,
`ordered_news_table`.`publish_time`,
`ordered_news_table`.`rank`,
FROM (select * from news ORDER BY `news_news`.`publish_time` DESC, `news_news`.`rank` DESC ) as ordered_news_table
INNER JOIN `news_tags_news`
ON ( `ordered_news_table`.`id` = `news_tags_news`.`news_id` )
INNER JOIN `news_tags`
ON ( `news_tags_news`.`tags_id` = `news_tags`.`id` )
WHERE (
`news_tags`.`tag_name` = 'someTag'
AND `ordered_news_table`.`publish_time` >= '2011-09-01'
AND `ordered_news_table`.`publish_time` <= '2016-05-10'
)
LIMIT 9;
но я нашел способ сделать это. Как я могу оптимизировать запрос? Я не хочу писать сырой sql. Я также пробовал __in, но у меня ничего не получилось, __in вызовет сортировку файлов.