基本上我想为每个主机获取最新的30个日志条目。目前我在django-piston中这样做。
def read(self,request):
val={}
for x in Host.objects.all():
val[x.uuid_id]=DataLog.objects.filter(host=x).order_by('-time')[:30]
return val
不幸的是,这个请求需要很长时间(目前大约10k数据库条目为1s)。 有更有效的方法吗?
哈珀
答案 0 :(得分:3)
如果您使用PostgreSQL作为数据库后端并且不需要跨数据库兼容性,则可以使用powerful window functions允许类似的内容:
想象一下你的表是这样的:
CREATE TABLE x (
i serial primary key,
value integer not null,
date timestamp,
category text);
您想要每个类别的最新价值。你会这样做:
SELECT
first_value(i) over w,
first_value(value) over w,
first_value(date) over w
category,
FROM x
WINDOW w AS (PARTITION BY category ORDER BY date DESC);
您可以通过查询集管理器上的raw
方法在django中使用此类查询:
ModelX.objects.raw("""SELECT DISTINCT ....... FROM x WINDOW w .....""")
要按类别获取最后N个条目,查询会更复杂并涉及子查询:
SELECT i, value, date, category
FROM (SELECT
i, value, date, category,
row_number() over w
FROM x
WINDOW w AS (PARTITION BY category ORDER BY date DESC)) AS subquery
WHERE subquery.row_number <= 30;
看到这一点,你甚至可以发表观点:
CREATE VIEW x_with_reverse_date_index AS
(SELECT
i, value, date, category,
row_number() over w
FROM x
WINDOW w AS (PARTITION BY category ORDER BY date DESC));
创建一个查询此视图的django模型:
class ModelX(models.Model):
...
...
row_number = models.IntegerField("Row number when ordering by date desc")
class Meta:
db_table = 'x_with_reverse_date_index'
并“正常”查询:
ModelX.objects.filter(category__in = ('catA','catB'), row_number__lte = 30)
ModelX.objects.filter(row_number = 29)
...
警告:如果您需要适用于其他数据库引擎的代码,请不要这样做。