View in Telegram
این داستان: وقتی خودمون با دست خودمون N+1 می‌سازیم! یکی از مهم‌ترین موضوعات زمانی که داریم اطلاعات رو از دیتابیس می‌خونیم، هزینه‌های پنهانی هستش که خودمون در هنگام نوشتن کوئری ایجاد می‌کنیم و حواسمون نیست. به کوئری زیر دقت و فرض کنید اپلیکیشنی مشابه اینستاگرام داریم و می‌خوایم خیلی ساده در یک کوئری پست‌ها و تعداد لایک‌ها رو از دیتابیس فراخوانی کنیم.
SELECT
    posts.id,
    posts.caption,
    posts.content_url,
    COALESCE(
        (
         SELECT COUNT(*)
         FROM post_reactions
         WHERE post_reactions.post_id = posts.id
        ),
        0
    ) AS reactions_count
FROM
    posts LEFT JOIN post_reactions ON post_reactions.post_id = posts.id
اگر با بعضی واژه‌ها در کوئری بالا آشنا نیستید مهم نیست، هدف ما بررسی ساب‌کوئری:
 SELECT COUNT(*)
       FROM post_reactions
         WHERE post_reactions.post_id = posts.id
ساب‌کوئری بالا رو میشه با روش‌های دیگه‌ای هم نوشت و تقریبا همه ما عادت کردیم در بسیاری از موارد وقتی میخوایم دیتایی مرتبط با نتایج مورد نظرمون از جدول‌های دیگه فراخوانی کنیم سریعا سراغ ساب‌کوئری‌ها بریم. اما باید دقت کنیم که این ساب‌کوئری‌ها در دل خودشون یک N+1 ایجاد میکنن و به‌ ازای تک‌تک ریف‌هایی که فراخوانی کردیم، تکرار میشن و به‌راحتی ما رو در رکوردهای بالا دچار مشکل میکنن! راه‌حل چنین موضوعاتی استفاده از pre aggregating و CTE هستش. بهتره در چنین مواقعی با استفاده از WITH در PostgreSQL یا MySQL یا MariaDB از تکرار کوئری‌ها به‌صورت پنهان در Joinها جلوگیری کنیم. نسخه اصلاح شده کوئری:
WITH
    reaction_counts AS (
        SELECT post_id, COUNT(*) AS reactions_count
        FROM post_reactions
        GROUP BY
            post_id
    ),
SELECT
            posts.id,
            posts.caption,
            posts.content_url,
            reaction_counts.reactions_count
FROM
        LEFT JOIN reaction_counts ON reaction_counts.post_id = posts.id
کوئری بالا هم خوانایی بیشتری داره و هم پرفورمنس بهتری! کاری که هیچ ORM درکی از انجامش نداره! #episode_0 #story #tip
Love Center - Dating, Friends & Matches, NY, LA, Dubai, Global
Love Center - Dating, Friends & Matches, NY, LA, Dubai, Global
Find friends or serious relationships easily