আপনার SQL দ্রুত কিন্তু API ধীরগতির

আপনার ডাটাবেস কুয়েরিগুলো দ্রুত। আপনার ক্যাশিং ঠিকঠাক কাজ করছে। আপনার ব্যাকগ্রাউন্ড জবগুলোও ঠিক আছে।

তবুও, আপনার API এখনও ধীরগতির। আপনার CPU ব্যবহার অনেক বেশি।

সমস্যাটি আপনার ডাটাবেসে নয়। সমস্যাটি হলো Ruby লেয়ারে।

ডাটা ডাটাবেস থেকে বেরিয়ে আপনার অ্যাপ্লিকেশনে প্রবেশ করার পর প্রায়শই এই বাটলনেক (bottleneck) তৈরি হয়। এটি মূলত তিনটি প্রধান সমস্যার কারণে ঘটে:

  • অতিরিক্ত সিরিয়ালাইজেশন (Bloated serialization)
  • অতিরিক্ত অবজেক্ট অ্যালোকেশন (Excessive object allocation)
  • বারবার একই গণনা (Repeated computation)

এগুলো কীভাবে সমাধান করবেন তা নিচে দেওয়া হলো।

১. অতিরিক্ত সিরিয়ালাইজেশন বন্ধ করুন

অনেক ডেভেলপার পুরো মডেলকেই JSON-এ রূপান্তর করেন।

render json: @shipments

যদি একটি শিপমেন্টে ৪০টি কলাম থাকে কিন্তু আপনার ফ্রন্টএন্ডের মাত্র ৫টি প্রয়োজন হয়, তবে আপনি অহেতুক CPU সাইকেল নষ্ট করছেন। এর ফলে API key বা খরচের মতো ব্যক্তিগত তথ্য ফাঁস হওয়ার ঝুঁকিও থাকে।

সমাধান: শুধুমাত্র প্রয়োজনীয় ফিল্ডগুলো রিটার্ন করুন।

render json: @shipments.as_json(only: [:id, :tracking_no, :status])

আরও দ্রুত গতির জন্য, ডাটা অ্যারে হিসেবে পেতে pluck ব্যবহার করুন। এটি ভারী ActiveRecord অবজেক্ট তৈরি করার ঝামেলা পুরোপুরি এড়িয়ে চলে।

২. অবজেক্ট অ্যালোকেশন কমান

Ruby প্রতিটি অবজেক্ট তৈরির জন্য মেমরি খরচ করে। একটি মাত্র রিকোয়েস্টের সময় হাজার হাজার অবজেক্ট তৈরি করলে Garbage Collector (GC)-কে অনেক বেশি কাজ করতে হয়। এটি আপনার পুরো সিস্টেমকে ধীর করে দেয়।

লুপের ভেতরে নতুন hash বা string তৈরি করা এড়িয়ে চলুন।

খারাপ:

@shipments.map do |s|
  { label: "#{s.tracking_no} - #{s.status.upcase}" }
end

ভালো: স্ট্যাটিক ডাটা লুপের বাইরে নিয়ে আসুন। Ruby-র পরিবর্তে ডাটাবেসে বেশি কাজ করার চেষ্টা করুন।

৩. বারবার একই গণনা এড়িয়ে চলুন

আপনি যদি একটি রিকোয়েস্টের মধ্যে একই মেথড বারবার কল করেন, তবে আপনি সময় নষ্ট করছেন।

উদাহরণ:

def total_weight
  shipments.sum(&:weight)
end

যদি আপনার view, helper এবং serializer—সবগুলোই এটি কল করে, তবে আপনি তিনবার যোগফল গণনা করছেন।

সমাধান: memoization ব্যবহার করুন।

def total_weight
  @total_weight ||= shipments.sum(&:weight)
end

এটি নিশ্চিত করে যে প্রতিটি রিকোয়েস্টের জন্য গণনার কাজটি মাত্র একবারই হবে।

সারসংক্ষেপ টেবিল:

  • অতিরিক্ত সিরিয়ালাইজেশন: শুধুমাত্র প্রয়োজনীয় ফিল্ড রিটার্ন করুন অথবা pluck ব্যবহার করুন।
  • উচ্চ অ্যালোকেশন: লুপের মধ্যে কম অবজেক্ট তৈরি করুন।
  • বারবার গণনা: ফলাফল পুনরায় ব্যবহার করতে memoization ব্যবহার করুন।

ডাটাবেস অপ্টিমাইজেশান মানে হলো কম ডাটা চাওয়া। অ্যাপ্লিকেশন অপ্টিমাইজেশান মানে হলো ডাটা পাওয়ার পর অপ্রয়োজনীয় কাজ কমিয়ে আনা।

Source: https://dev.to/danewu/your-sql-is-fast-but-the-api-is-slow-its-the-ruby-layer-2fno