لماذا تفضل النطاقات القضبان ، إذا كانت وحدات التحكم الفوضوية أسرع؟

StackOverflow https://stackoverflow.com/questions/4314273

سؤال

لقد كنت أحاول سلسلة استعلامات Arel باستخدام النطاقات ، بدلاً من مجرد استخدام بعض المنطق الطويل الذي كتبته في وحدة التحكم. لكن النطاقات أبطأ من مجرد الحصول على جميع السجلات ثم تغربها ببعض المنطق. أنا أتساءل ، إذن ، لماذا النطاقات أفضل.

هذا ما أفعله:

  • سؤال له العديد من الإجابات
  • إجابة تنتمي إلى سؤال واحد
  • يحتوي السؤال على عمود "Question_type" الذي أستخدمه لفرزه

أولاً ، طريق النطاقات ...

في السؤال. rb:

scope :answered, joins(:answers).order('answers.created_at desc')
scope :dogs, where(:question_type => "dogs")
scope :cats, where(:question_type => "cats")
scope :mermaids, where(:question_type => "mermaids")

في Question_Controller.rb:

@dogs_recently_answered = Question.answered.dogs.uniq[0..9]
@cats_recently_answered = Question.answered.cats.uniq[0..9]
@mermaids_recently_answered = Question.answered.mermaids.uniq[0..9]

ثم في العرض ، أقوم بتدوير متغيرات المثيل هذه (التي أصبحت الآن صفائف تحتوي على أكثر من 10 عناصر) وعرض النتائج.

فيما يلي الأوقات التي يستغرقها تحميل الصفحة (خمس مرات مختلفة):

أكمل 200 موافق في 535ms (وجهات النظر: 189.6ms | ActivereCord: 46.2ms)

أكمل 200 موافق في 573 مللي ثانية (وجهات النظر: 186.0 مللي ثانية | ActivereCord: 46.3ms)

أكمل 200 موافق في 577 مللي ثانية (وجهات النظر: 189.0ms | ActivereCord: 45.6ms)

أكمل 200 موافق في 532ms (وجهات النظر: 182.9ms | ActivereCord: 46.1ms)

أكمل 200 موافق في 577 مللي ثانية (وجهات النظر: 186.7 مللي ثانية | ActivereCord: 46.9ms)

الآن ، طريقة تحكم الفوضى ...

@answers = Answer.order("created_at desc")
@all_answered = []
@answers.each {|answer| @all_answered << answer.question}
@recently_answered = @all_answered.uniq
@dogs_all_answered = []
@cats_all_answered = []
@mermaids_all_answered = []
@recently_answered.each do |q|
  if q.question_type == "dogs"
    @dogs_all_answered << q
    @dogs_recently_answered = @dogs_all_answered[0..9]
  elsif q.question_type == "cats"
    @cats_all_answered << q
    @cats_recently_answered = @cats_all_answered[0..9]
  elsif q.question_type == "mermaids"
    @mermaids_all_answered << q
    @mermaids_recently_answered = @mermaids_all_answered[0..9]
  end
end

وإليك الأوقات التي تستغرقها لتحميل الصفحة الآن (خمس مرات مختلفة):

أكمل 200 موافق في 475 مللي ثانية (وجهات النظر: 196.5ms | ActivereCord: 34.5ms)

أكمل 200 موافق في 480ms (وجهات النظر: 200.4 مللي ثانية | ActivereCord: 36.4ms)

أكمل 200 موافق في 434ms (وجهات النظر: 198.2 مللي ثانية | ActivereCord: 35.8ms)

أكمل 200 موافق في 475ms (وجهات النظر: 194.2ms | ActivereCord: 36.4ms)

أكمل 200 موافق في 475ms (وجهات النظر: 195.0ms | ActivereCord: 35.4ms)

لذا...

بصرف النظر عن قابلية القراءة ، ما الذي يجب الفوز به من خلال شحذ الاستعلام بنطاق؟ هل تصبح في النهاية أسرع عندما يكون هناك المزيد من السجلات؟

هل كانت مفيدة؟

المحلول

أولاً ، لست متأكدًا من أنني أفهم كيف يمكن أن يكون السؤال غير الفريد ، لذلك سألقي نظرة على محاولة إزالة ذلك. لا أعرف منطق بياناتك ، بحيث لا يكون ذلك قابلاً للتطبيق ، ولكنها خطوة إضافية قد تكون قادرًا على تجنبها.

إليكم كيف سأقترب منه:

scope :answered, joins(:answers).order('answers.created_at desc')
scope :recent, take(10)
scope :dogs, where(:question_type => "dogs")
scope :cats, where(:question_type => "cats")
scope :mermaids, where(:question_type => "mermaids")

@dogs_recently_answered = Question.answered.dogs.recent
@cats_recently_answered = Question.answered.dogs.recent
@mermaids_recently_answered = Question.answered.dogs.recent

هذا يغير TOP جزء من الاستعلام إلى قاعدة البيانات حيث ينتمي بدلاً من الجلب الكل من الصفوف ثم التخلص من كل ما عدا 10

scope :unique, select('DISTINCT column_name')

وبعد ذلك ، يمكنك استخدام Question.cats.unique.recent والحصول على كل شيء في استعلام سريع واحد يعزز الجبر العلائقي الذي تم تصميم أنظمة قاعدة البيانات من أجله.

نصائح أخرى

أعتقد أن السبب في أن النطاقات أبطأ في هذه الحالة هو أنها تؤدي إلى 3 استعلامات منفصلة لقاعدة البيانات ، في حين أن النهج الآخر يستخدم المعرفة بأن جميع النتائج الثلاثة يمكن أن تكون راضية عن طريق الاستعلام الوحيد الذي تستخدمه.

على افتراض أن هذا هو الحال ، فليس من المستغرب أن يقوم النطاقات بثلاث استفسارات منفصلة لأن النظام لا يعرف متى تتصل بالسلطة الأولى التي ستتصل بها الآخرين بعد ذلك. ربما هناك استراتيجية تحسين من شأنها أن تكون معقولة لهذا السيناريو ، لكنني لا أعرف أن ActivereCord ينفذها.

على أي حال ، هذا هو عيب واحد للنطاق في هذه الحالة بالذات. أنا أحب النطاقات لأنها نظيفة/واضحة ومرنة وتغليف تجريد تسمية للاستعلام. AFAICT ، في العديد من السيناريوهات ليست أبطأ بشكل ملحوظ من الاستعلام المباشر المكافئ.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top