2016-09-14 6 views
0

これは、電子メールのリストが250,000〜250,000件に及んでいることです。データベースの稼働時間を短縮するDjango/Mysql

私は第1のテーブルから削除する必要がある無効な電子メールのリスト〜50,000を含む別のテーブルを持っています(無効にする)。そのために、私は各ループで3-4秒かかる単純なdjango関数を実行しました。コードは次のとおりです。

def clean_list(): 
    id = 9 
    while id<40000: 
     i = Invalid.objects.get(id=id) 
     y = i.email.strip() 
     f = IndiList.objects.get(email__contains=y) 
     f.active = False 
     f.save() 
     id +=1 

これを行うにはどうすればよいでしょうか? SQLクエリか、より優れたdjangoコードまたはその他の方法。

ヘルプ!

答えて

1

未テスト:

IndiList.objects.filter(email__in=Invalid.objects.only('email').all()).update(active=False) 

私がいない場合は、これが何をすべき、Djangoはそのからサブクエリを構築するために十分にスマートであるかどうかわからないです:

IndiList.objects.filter(email__in=Invalid.objects.all().values_list('email', flat=True)).update(active=False) 

第二のアプローチの問題点1つではなく2つのクエリを生成し、2番目のSQLクエリ文字列に50,000のIDを挿入するので、この時点でraw SQLを使用するだけです。

from django.db import connection 

cursor = connection.cursor() 
cursor.execute = 'UPDATE indilist SET active=false WHERE email IN (SELECT email FROM invalid)' 
+0

正確には、Raw SQLは高速です。 – sprksh

1

いくつかの最適化があります。代わりに、各オブジェクトの取得をループの値のリストを取得してみてください。

queryset = Invalid.objects.filter(id__range=(9,40000)) queryset_list = queryset.values_list('email' flat=True)

https://docs.djangoproject.com/en/1.10/ref/models/querysets/#values-list

は、値のリストをループし、電子メールにに.get()を実行。終わりに、あなたも行うことができます唯一のブールフィールドを更新します

f.active = False f.save(update_fields=['active'])

を。 https://docs.djangoproject.com/en/1.10/ref/models/instances/#updating-attributes-based-on-existing-fields

可能であれば、idや他のフィールドを使用してオブジェクトを.get()する方法も見つけようとします。

0

数回繰り返した後、私はより1000倍速かったこの機能を使用しました。

def clean_list3(): 
    pp = Invalid.objects.filter(id__gte=9) 
    listd = [oo.email.strip() for oo in pp] 
    for e in IndiList.objects.all(): 
     if e.email.strip() in listd: 
      e.active=False 
      e.save() 
      print(e.id) 

トリックではなく、データベースのすべての時間を打つ、私はメモリ内のクエリセット25万個のオブジェクトを保存し、簡単です。メモリ内の無効なリストからの電子メールのリストも表示されます。

私はそれを非アクティブとして保存するために一致するメールが見つかったときにのみデータベースにヒットしなければなりませんでした。

関連する問題