我使用以下代码从数据库中选择热门新闻条目(按日期):
popular = Entry.objects.filter(type='A', is_public=True).extra(select = {'dpub': 'date(dt_published)'}).order_by('-dpub', '-views', '-dt_written', 'headline')[0:5]
为了比较普通查询和这个查询的执行速度,我运行了以下mysql查询:
SELECT *, date(dt_published) as dpub FROM `news_entry` order by dpub DESC LIMIT 500
# Showing rows 0 - 29 (500 total, Query took 0.1386 sec)
-
SELECT * , DATE( dt_published ) AS dpub FROM `news_entry` ORDER BY id DESC LIMIT 500
# Showing rows 0 - 29 (500 total, Query took 0.0021 sec) [id: 58079 - 57580]
正如您所看到的,正常查询要快得多。有没有办法加快速度呢?
是否可以在django中使用mysql视图?
我意识到我可以将日期时间字段分成两个字段(日期和时间),但我很好奇。
CREATE TABLE IF NOT EXISTS `news_entry` (
`id` int(11) NOT NULL DEFAULT '0',
`views` int(11) NOT NULL,
`user_views` int(11) NOT NULL,
`old_id` int(11) DEFAULT NULL,
`type` varchar(1) NOT NULL,
`headline` varchar(256) NOT NULL,
`subheadline` varchar(256) NOT NULL,
`slug` varchar(50) NOT NULL,
`category_id` int(11) DEFAULT NULL,
`is_public` tinyint(1) NOT NULL,
`is_featured` tinyint(1) NOT NULL,
`dt_written` datetime DEFAULT NULL,
`dt_modified` datetime DEFAULT NULL,
`dt_published` datetime DEFAULT NULL,
`author_id` int(11) DEFAULT NULL,
`author_alt` varchar(256) NOT NULL,
`email_alt` varchar(256) NOT NULL,
`tags` varchar(255) NOT NULL,
`content` longtext NOT NULL
) ENGINE=MyISAM DEFAULT;
答案 0 :(得分:2)
SELECT *, date(dt_published) as dpub FROM `news_entry` order by dpub DESC LIMIT 500
此查询在dpub
上排序,而这一个:
SELECT * , DATE( dt_published ) AS dpub FROM `news_entry` ORDER BY id DESC LIMIT 500
id
上的订单。
由于id
很可能是您的表的PRIMARY KEY
,并且每个PRIMARY KEY
都有一个支持它的隐式索引,ORDER BY
不需要排序。
dpub
是计算字段,MySQL
不支持计算字段的索引。但是,ORDER BY dt_published
也是ORDER BY dpub
。
您需要将查询更改为:
SELECT *, date(dt_published) as dpub FROM `news_entry` order by date_published DESC LIMIT 500
并在news_entry (dt_published)
上创建索引。
<强>更新强>
由于DATE
是一种单调函数,你可以使用这个技巧:
SELECT *, DATE(dt_published) AS dpub
FROM news_entry
WHERE dt_published >=
(
SELECT md
FROM (
SELECT DATE(dt_published) AS md
FROM news_entry
ORDER BY
dt_published DESC
LIMIT 499, 1
) q
UNION ALL
SELECT DATE(MIN(dt_published))
FROM news_entry
LIMIT 1
)
ORDER BY
dpub DESC, views DESC, dt_written DESC, headline
LIMIT 500
此查询执行以下操作:
选择500th
订单中的dt_published DESC
记录,或者如果表中的记录少于500
,则会发布第一条记录。
获取所有在所选最后一条记录的日期之后发布的记录。由于DATE(x)
始终小于或等于x
,因此可能会有超过500
个记录,但仍然
比整张桌子要少得多。
根据需要对这些记录进行排序和限制。
您可能会发现这篇文章很有趣,因为它涵盖了类似的问题:
答案 1 :(得分:0)
可能需要dt_published
上的索引。你能发布两个查询的查询计划吗?