انجمن برنامه نویسان البرز

تبلیغات

چرا استفاده از Stored Procedure غلط است؟

چرا استفاده از Stored Procedure غلط است؟


در طول عمر برنامه نویسی ام، همیشه یک دعوای ناتمام بر سر استفاده کردن یا استفاده نکردن از Stored Procedure ها داشته ام.

دلایل بسیاری را شنیده ام و کدورت های زیادی بین من و مخالفانم پیش آمده.

در این مقاله باورهای غلط در مورد Stored Procedure ها را توضیح میدهم.

قبل از هر چیز باید مشخص کنم که موضع من، “مخالفت با Stored Procedure ها” است. بنابراین اگر در انتهای این مقاله، نظری در رابطه با مطالب داشتید، خوشحال میشوم نظر شما را هم بدانم.

و اما برویم سراغ باورهای غلطی که درباره Stored Procedure ها وجود دارد:

 

آیا Stored Procedure واقعا سریعتر است؟

این اولین دفاعی است که آدم های بی مطالعه، برای اثبات حقانیت استفاده از SP ها ارائه میکنند. اما ببینیم که این دلیل جقدر صحیح است. سریعتر بودن SP را از ۲ منظر میتوان بررسی کرد:

متن کوئری ای که بین برنامه و SQL Engine رد و بدل میشود:

در این حالت، در صورت استفاده از SP، نام SP به همراه لیستی از پارامترها به SQL Engine پاس داده میشود. در صورت استفاده از کوئری های Inline و یا ORM بدون SP، لیست پارامترها به همراه دستورات SQL به دیتابیس پاس داده میشود. آیا برنامه های ما آنقدر بهینه است که با خطوطی که سرعت ترانسفر دیتای آنها در بدترین حالت ۱۲۸۰۰۰ بیت بر ثانیه است، نگران یکی ۲ بیت text باشیم؟

SP ها قبل از اجرا، Plan میشوند:

Plan شدن به این معنی است که قبل از اجرا کردن یک SP، موتور sql بهترین روش برای اجرای آنرا برنامه ریزی میکند. برای اینکه بهتر متوجه شوید، در نظر بگیرید که دو جدول STUDENT و TEACHER دارید که به هم رابطه یک به چند دارند. هر کدام از جدول ها هم ۱ میلیون رکورد دارند. کوئری زیر را در نظر بگیرید:
Select * from Student inner join Teacher on Student.TeacherID=Teacher.ID where Student.Mark>10

اگر روش اجرای کوئری به این شکل باشد که ابتدا جدول Student با جدول Teacher با هم Innerjoin شوند و بعد شرط Where بر روی آنها انجام شود و دانش آموزانی که نمره بالاتر از ۱۰ دارند انتخاب شوند، رسیدن به جواب، کلی طول میکشد.

چون تعداد رکوردهای join شده برابر با ضرب دکارتی دو جدول خواهد بود. اما SQL Engine آنقدرها هم احمق نیست. کاری که SQL Engine انجام میدهد، این است که اول شرط را بر قرار میکند و رکوردهایی از Student را که در شرط هستند، با Teacher ترکیب میکند. به این پروسه هوشمند، Plan کردن میگویند.

نکته مهم این است که چه شما از SP استفاده کنید و چه از کوئری و ORM، داستان Plan کردن سر جایش هست و جایی نمیرود! پس این دلیل غلط است که بگوییم به علت Plan شدن، SP ها سریعتر عمل میکنند.

آیا استفاده از SP تغییرات درخواستی مشتری را سریعتر میکند؟

این جمله را خیلی زیاد شنیده ام که خوبی SP این است که وقتی مشتری تغییراتی میخواهد، دیگر نیاز نیست برنامه را تغییر بدهیم. ببینید. تغییرات ۲ دسته هستند.

تغییراتی که باعث میشوند مجبور شویم UI را تغییر بدهیم. درباره این دسته از تغییرات که صحبتی نیست.

تغییراتی که ناشی از عملکرد غلط کدهای لاجیک هستند. منظور از سرعت تغییرات، از دید این دوستان، همین مورد دوم است.

موضوع انجام تغییرات وقتی حاد تر میشود که گروهی این دلیل را مطرح میکنند:

فرض کن ۱۰۰ نسخه از یک برنامه فروختی و میخواهی تغییری در لاجیک آن به وجود بیاوری. در صورت استفاده از SP فقط SP مربوطه را آپدیت میکنی.

سوالی که من از این دسته از افراد میپرسم، معمولا این است: آیا ۱۰۰ نسخه نرم افزار شما، به یک دیتابیس به طور مستقیم متصل میشوند؟ اگر اینطور است که وای به حال شما و کدنویسی تان!

وقتی برنامه ای ۱۰۰ تا مشتری دارد، قطعا باید بین دیتابیس و کلاینت ها، یک API یا وب سرویس داشته باشد، پس در صورت نیاز به تغییرات، فقط API را اصلاح میکنید.

 

و اما در ادامه ضعف های بزرگ SP را بررسی میکنیم:

SP قابل دیباگ کردن نیست!

SP قابلیت ورژن کنترل ندارد.

نوشتن کد در SP سلیقه ای بوده و Design Pattern خاصی ندارد.

در صورت استفاده از Temp Table، و EF Databasefirst یا Linq to sql قادر نخواهید بود شمای SP را به طور اتوماتیک بسازید.

قادر نیستید برای SP یونیت تست بنویسید.

 

قضاوت با شما!

شاید این مطلب را هم بپسندید.




کلمات کلیدی :

نظر بدهید

11 دیدگاه برای “چرا استفاده از Stored Procedure غلط است؟

  • محسن گفته
    23 جولای 18

    سلام دوست عزیر
    من مطالب شما رو به صورت کامل مطالعه کردم

    با احترام.به نظرم تجربه کافی رو در خصوص پروژه های big scale ندارین

    استفاده از sp برای نظم کد نویسی برنامه در لایه های مختلف بسیار مهمه
    شما یه کوئری رو تو برنامت هارد کد کنی بهتره یا تو دیتابیس نگهداریش کنی؟؟؟
    شما فرض کن یه کوئری پیچیده داری که نیاز یه تغییرات داره یه sp ازش میسازی و میدی دست تیم مدیریت دیتابیس و تغییرات رو میدن و برنامه نویس ازش استفاده می کنه بدون اینکه تو توسعه ایستایی پیش بیاد و یا تو کارهای همدیگه سرک بکشن

    بارها برای خودم پیش اومده تیم پشتیبانی برای نصب رفتن یه شهر دیگه زنگ زدن که مهندس فلان جا یه همچین ایرادی وجود داره
    بررسی کردم دیدم کد محاسباتی که ازش sp ساختم ایراد داره
    اصلاح کردم اسکریپت دادم سریع مشکل حل شده
    در صورتی که اگه قرار بود برای هر ایراد یه نسخه بیلد کنم کلی زمان به هدر می رفت
    فقط بیلد پروژه ای که دارم نیم ساعت طول میکشه!
    بماند که بحث آپلود و دانلود یه پروژه با حجم سی مگابایت رو هم داریم که باز خودش کلی زمان میبره
    مخصوصا تو محل مشتری که دسترسی به اینترنت هم سخته
    مخصوصا در شهر های دیگه

    از طرفی هم بحث یکی دو بیت اینور اونور هم مهمه اونم وقتی یه کوئری در روز چند میلیون بار صدا زده بشه
    بماند کخ با سبک شما تقریبا تمام کوئری ها در بهترین حالت یکی دو بیت سر بار دارن. ولی در کل خارج از بحث ترانسفر شبکه بحث بیزی شدن سرور هم در نظر بگیرین.

    • علیرضا صبوئی گفته
      23 جولای 18

      محسن عزیز اول از همه ممنونم از بابت زمانی که صرف خوندن مقاله من کردید. بسیار برام ارزشمنده و ازتون سپاسگزارم.
      همونطور که خدمتتون عرض کرده بودم (در مقاله) تغییرات در حوزه لاجیک، ۲ نوع هستند:
      ۱٫ تغییراتی که منجر به ایجاد نیاز برای یک تغییر در UI هم میشوند.
      ۲٫ تغییراتی که در حوزه لاجیک انجام میشوند و منطق مخاسباتیو عوض میکنن.
      در مورد دسته اول که بحثی نیست. از اونجا که فارغ از هر روشی که استفاده کنیم، (SP یا ORM یا Query) نیاز به Rebuild خواهیم داشت.
      در مورد دسته دوم، همونطور که ذکر کردم، در صورتی که برنامه شما به طور مستقیم از دیتابیس و SP های اون استفاده میکنه و از معماری سرویس گرا خبری نیست، مشکلاتتون ۱۰۰ برابر میشه. به عنوان مثال میتونم به زمانی که برای عملیات وصل شدن به دیتابیس، هندزشیکینگ و سایر سربارها نیازه اشاره کنم.
      پس اگر در مورد یک محیط Enterprise صحبت میکنیم، پیاده سازی بدون استفاده از سرویس گرایی، گزینه روی میز نیست.

      در مورد اینکه نباید در کار هم سرک بکشیم هم باید عرض کنم این استاندارد، در چارچوب اسکرام، منسوخ شده هستش. اسکرام از برنامه نویس های Full Stack استفاده میکنه.

      در کنار اینها دوست دارم نظر شما رو در رابطه با ۲ مشکل اساسی ورژن کنترل دیتابیس و دیباگینگ، در صورت استفاده از SP ها بدونم محسن عزیزم.

      دوستدار شما. علیرضا صبوئی

    • علیرضا صبوئی گفته
      23 جولای 18

      مورد دیگری که فراموش کردم بگم و از همه مهم تره. اینه که یک پروژه Enterprise بدون Unit Testing مفهومی نداره. با استفاده از SP شما بخش اعظم لاجیک نرم افزار رو در جایی کپسوله میکنید که قابلیت Unit Testing نداره. و این بزرگترین مشکل SP هستش.

    • علیرضا صبوئی گفته
      23 جولای 18

      با احترام.به نظرم تجربه کافی رو در خصوص پروژه های big scale ندارین

      با کمال احترام، به نظرم این جمله و این قضاوت، کمی خارج از اخلاق حرفه ایه

  • احمد شاه پوری گفته
    23 جولای 18

    با سلام
    آیا برای برنامه ای که بر روی شبکه داخلی (lan) با تعداد کاربر زیاد هم باید api استفاده کنیم؟

    • علیرضا صبوئی گفته
      23 جولای 18

      بله این گزینه هم میتونه استفاده بشه.

  • محمد گفته
    23 جولای 18

    با سلام و خسته نباشید
    مقاله جالبی بود. اگر اجازه بدید لینک مقالتون رو در گروه های تخصصی ارسال کنم.

    آمار بازدیدتون هم میره بالا 🙂

    • علیرضا صبوئی گفته
      23 جولای 18

      محمد عزیز ممنون از شما. نیکی و پرسش؟

  • صابر گفته
    23 جولای 18

    هر سخن وقتی و هر نکته مکانی دارد.

    با این دید که SP بده SQL Query خوب اصلا موافق نیستم، مثالی عرض کنم.
    فرض کنیم به ما بگن با یه وسیله نقلیه به انتخاب خودت برو شمال و بیست نفر رو هم همراهت ببر.

    حالا شما تو این شرایط چه وسیله ای رو انتخاب میکنی؟ اتوبوس یا کوپه دونفره؟

    خوب شما باید ببینی چه چالش پیش روت داری و با توجه به اون انتخاب کنی SP خوبه یا Query.

  • دیوید رابرت گفته
    23 جولای 18

    سلام و خسته نباشید.
    دوست عزیز بنده مقاله شما رو مطاله کردم. و همین طور کامنت ها رو خوندم.
    بحث تجربه که تو این چند سال داشتم عملی نه تئوری چون برنامه نویسی عملی بدون توضیحات یاد گرفتم.
    در برنامه نویسی در روش ADO بخواهی کد داخل پروژه به کار ببرید مکافات ها کم نمیشه زیاد هم میشه و دیباگ یابی تو کوئری داخل برنامه سخت میشه ولی وقتی داخل SP بیای کوئری نویسی کنید که تازه من کوئری نویسی زیاد دیگه انجام نمیدم چون خود اسکیول کوئری برای من مینویسه و اگه کوئری ایراد داشته باشه بهم میگه به همین خاطر خطایابی تو SP راحتر و سریعتر هستش و برنامه ویندوز که تحت شبکه باشه اگه یک مشکل تو کوئری پیش بیاد بدون اینکه من نسخه جدید آماده و آپلود و دانلود کنه مشتری و همین طور برنامه مشتری من نبنده و باز بمونه میتونم کوئری به روز کنم یعنی داخل پروسیجر کوئری ام به روز میکنم و مشکل تمام کاربرام هم حل میشه تازه برنامه هم نمیبندن. این مزیت خیلی خوب SP هستش ولی بخواهی با تکنولوژی ضعیف مثل EF و Linq کار کنیم دو تا مشکل بزرگ داریم یک کند بودن شدید پروژه در این پروژه و دوم کدهای سنگین که برای دیباگ یابی پست آدم کنده میشه مثلا من کوئری که ۱۵ تا Join و چند شرط داره داخل کوئری میخوام داخل SP بنویسم تو ۱ دقیقه یا کمتر تمام میشه ولی تو EF و یا Linq ساعت ها باید وقت بزارم بنویسم تازه اشتباه باشه و یا کار نکنه یعنی یک پست کنندن قشنگ داره و یا ADO داخل پروژه بنویسی پیدا کردن خطا داخل اونم یک مشکل دیگه ولی وقتی از پروسیجر استفاده کنی هم سرعت لود بالا داری و هم سرعت کوئری نویسی بالا. و در آخر خطایابی بهتری داری نسبت بهم من یک پروسیجر برای یک جدول میسازم و داخل همون پروسیجر که برای یک جدول همه کوئری مثل ذخیره ویرایش و حذف و انواع نمایش مینویسم و راحتر تر میتونم مدیریت کنم تا اینکه پخش پلا کوئری نویسی کنم

    • علیرضا صبوئی گفته
      23 جولای 18

      دوست خوبم مشکل در استفاده غلط شما از EF هستش