使用django和sqlite的运行时问题 - 查询过多

时间:2017-04-26 11:50:49

标签: python mysql django python-2.7 sqlite

我遇到以下代码的运行时问题:

# filter start and end date
matches = database.objects.filter(start__gte= Start, end__lte= End)    
# iterate through matches
for Item in matches:
        # filter database again
        test = database.objects.filter(cm1=Item.cm1, cm2=Item.cm2, cm3=Item.cm3)
        # compare first item of filter with iterated Item
        if test[0] == Item:
            TrueRun = True
        else:
            TrueRun = False

我有一个大约80k行的数据库。在第一步中我过滤我想看的行,通常应该在8k左右。在第二步中,我会遍历所有这些项目并检查它们是否唯一,或者检查它们是否具有某些特定属性(cm1cm2cm3)。

现在的问题是,我做了8k数据库查询,这些查询大约需要15分钟。有没有办法加速这个,例如在循环之前使用一个dict,它包含cm1及其匹配行的所有可能性?

感谢您的帮助!

__________________________

评论后编辑

我的模型的默认顺序与此处使用的默认顺序不同。在程序中,我有大约25个模型,并检查其中12个是否相同。

循环的其余部分应该不是很有趣,因为之前还有另一种检查TrueRun的方法,大约需要2分钟。唯一改变的是#-----#见这里:

equalnessList = ['cm1','cm2', 'cm3']
for idx, Item in enumerate(matches):
    #-----------------#
    TrueRun = True
    listTrue = []
    for TrueIdx,TrueItem in enumerate(listTrue):
        EqualCount = 0
        for equCrit in equalnessList:
            if getattr(Item,equCrit)!=getattr(matches[TrueItem],equCrit):
                EqualCount += 1
        if EqualCount == len(equalnessList):
            TrueRun = False
            break
    #------------------#
    # Some stuff in here, that can't be changed
    if TrueRun:
        resDict[getattr(Item,'id')] = [True]
        listTrue.append(idx)
    else:
        resDict[getattr(Item,'id')] = [False]

问题在于,它无法正常工作,并且没有使用过滤日期之外的数据库条目进行检查。

2 个答案:

答案 0 :(得分:0)

ParseResult(String valInMS, boolean isInSeconds, boolean isUnder1MS)

答案 1 :(得分:0)

您可能需要调整它以满足您的要求。特别是,您需要在每个cm1, cm2, cm3组中维护原始排序顺序。

matches = database.objects.filter(start__gte=Start, end__lte=End)
all_objects = database.objects.all().order_by('cm1', 'cm2', 'cm3', 'sequence')
# replace 'sequence' by field(s) that model is sorted on by default
results_dict = {}
cm1 = None
cm2 = None
cm3 = None
first = False
for obj in all_objects:
    if (obj.cm1 != cm1) or (obj.cm2 != cm2) or (obj.cm3 != cm3):
        cm1 = obj.cm1
        cm2 = obj.cm2
        cm3 = obj.cm3
        first = True
    if obj.start >= Start and obj.end <= End:
        results_dict[obj.id] = first
    first = False