تسريع إدراج قاعدة بيانات من مكتب إدارة السجلات
-
05-07-2019 - |
سؤال
ولدي وجهة نظر جانغو مما يخلق 500-5000 الملاحق قاعدة بيانات جديدة في حلقة. المشكلة هي، أنها بطيئة حقا! أنا الحصول على حوالي 100 إدراج في الدقيقة الواحدة على بوستجرس 8.3. كنا استخدام الخلية على الأجهزة أقل (مثيل EC2 أصغر) وليس لديهم هذه الأنواع من القضايا السرعة.
والصفات: بوستجرس 8.3 على خادم أوبونتو 9.04. الخادم هو "كبيرة" أمازون EC2 مع قاعدة البيانات على EBS (ext3 و) - 11GB / 20GB
وهنا بعض من بلدي postgresql.conf - اسمحوا لي أن أعرف إذا كنت بحاجة إلى المزيد
shared_buffers = 4000MB
effective_cache_size = 7128MB
وبلدي الثعبان:
for k in kw:
k = k.lower()
p = ProfileKeyword(profile=self)
logging.debug(k)
p.keyword, created = Keyword.objects.get_or_create(keyword=k, defaults={'keyword':k,})
if not created and ProfileKeyword.objects.filter(profile=self, keyword=p.keyword).count():
#checking created is just a small optimization to save some database hits on new keywords
pass #duplicate entry
else:
p.save()
وبعض الانتاج من أعلى:
top - 16:56:22 up 21 days, 20:55, 4 users, load average: 0.99, 1.01, 0.94
Tasks: 68 total, 1 running, 67 sleeping, 0 stopped, 0 zombie
Cpu(s): 5.8%us, 0.2%sy, 0.0%ni, 90.5%id, 0.7%wa, 0.0%hi, 0.0%si, 2.8%st
Mem: 15736360k total, 12527788k used, 3208572k free, 332188k buffers
Swap: 0k total, 0k used, 0k free, 11322048k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14767 postgres 25 0 4164m 117m 114m S 22 0.8 2:52.00 postgres
1 root 20 0 4024 700 592 S 0 0.0 0:01.09 init
2 root RT 0 0 0 0 S 0 0.0 0:11.76 migration/0
3 root 34 19 0 0 0 S 0 0.0 0:00.00 ksoftirqd/0
4 root RT 0 0 0 0 S 0 0.0 0:00.00 watchdog/0
5 root 10 -5 0 0 0 S 0 0.0 0:00.08 events/0
6 root 11 -5 0 0 0 S 0 0.0 0:00.00 khelper
7 root 10 -5 0 0 0 S 0 0.0 0:00.00 kthread
9 root 10 -5 0 0 0 S 0 0.0 0:00.00 xenwatch
10 root 10 -5 0 0 0 S 0 0.0 0:00.00 xenbus
18 root RT -5 0 0 0 S 0 0.0 0:11.84 migration/1
19 root 34 19 0 0 0 S 0 0.0 0:00.01 ksoftirqd/1
واسمحوا لي أن أعرف إذا كان أي تفاصيل أخرى سيكون مفيدا.
المحلول
أولا، عمليات ORM ودائما ما يكون أبطأ من SQL النقي. كتبت مرة تحديثا لقاعدة بيانات كبيرة في التعليمات البرمجية ORM وضعه على التوالي، لكنه استقال بعد عدة ساعات عندما أكملت سوى نسبة ضئيلة. بعد إعادة كتابة في SQL ركض كل شيء في أقل من دقيقة.
وثانيا، أن تضع في الاعتبار أن التعليمات البرمجية هنا هو فعل ما يصل الى أربع عمليات قاعدة بيانات منفصلة عن كل صف في مجموعة البيانات الخاصة بك - وget
في get_or_create، وربما أيضا create
، وcount
على مرشح، وأخيرا save
. كما أن هناك العديد من الوصول إلى قاعدة البيانات.
واضعة في اعتبارها ما لا يزيد عن 5000 الأشياء ليست ضخمة، يجب أن تكون قادرا على قراءة بيانات كاملة في الذاكرة في البداية. ثم يمكنك القيام filter
واحد للحصول على كل الكائنات كلمات الموجودة في دفعة واحدة، وتوفير عدد كبير من الاستعلامات في get_or_create
الكلمات الرئيسية وتجنب أيضا على الحاجة إلى إنشاء مثيل ProfileKeywords مكررة في المقام الأول.
نصائح أخرى
وأحد الأسباب الشائعة لمعظم العمليات بطيئة مثل هذا هو كل إدراج يحدث في المعاملات الخاصة بها. إذا كان يمكنك الحصول على كل منهم أن يحدث في عملية واحدة، فإنه يمكن أن تذهب أسرع بكثير.