SQL روشی مناسب برای مدیریت و پرس و جوی داده های شما است، اما پرس و جوهای بد نوشته شده می توانند پایگاه داده شما را محدود کنند. در اینجا هفت تله رایج SQL و نحوه اجتناب از آنها آورده شده است.
توسعه دهندگان پایگاه داده مشکل دارند. خواه از SQL Server، Oracle، DB2، MySQL، PostgreSQL یا SQLite استفاده کنند، چالش ها مشابه هستند. نوشتن عبارتهایی که عملکرد بدی دارند، منابع سیستم را تلف میکنند یا از ویژگیهای پایگاه داده طراحیشده برای آسانتر کردن زندگی استفاده نمیکنند، بسیار آسان است.
در اینجا هفت تله رایج وجود دارد که هنگام نوشتن برنامه های پایگاه داده باید از آنها اجتناب کنید.
۷ اشتباه SQL که باید اجتناب شود
- استفاده مجدد کورکورانه از پرس و جوها
- نماهای تودرتو
- اجرای عملیات بزرگ و چند جدولی در یک تراکنش
- خوشهبندی در GUID یا سایر ستونهای “فرار”
- شمارش ردیف ها برای بررسی وجود داده
- استفاده از محرکها
- انجام جستجوهای منفی
استفاده مجدد کورکورانه از پرس و جوها
یک پرس و جوی SQL معمولاً برای بازیابی داده های مورد نیاز برای یک کار خاص تنظیم می شود. اگر یک پرس و جو را تغییر دهید که با بیشتر موارد استفاده شما مطابقت دارد، ممکن است ظاهراً کار کند، اما همچنین می تواند داده های زیادی را ارائه دهد. این کار باعث آسیب به عملکرد و منابع می شود، که برخی از آنها تا زمانی که مقیاس را به دست نیاورید آشکار نمی شوند. همیشه جستارهایی را که قصد دارید آنها را تغییر دهید بررسی کنید و آنها را به تناسب موارد استفاده جدید کوتاه کنید.
نماهای تودرتو
نماها روشی استاندارد برای مشاهده داده ها ارائه می دهند و کاربران را از مواجهه با پرس و جوهای پیچیده باز می دارد. مشکل زمانی ایجاد می شود که از view ها برای پرس و جو از نماهای دیگر استفاده می کنیم.
نماهای تودرتو، همانطور که اینها نامیده می شوند، دارای اشکالات متعددی هستند. به عنوان مثال، آنها داده های بسیار بیشتری از آنچه شما معمولاً نیاز دارید جستجو می کنند. آنها همچنین میزان کاری را که برای بازیابی مجموعه ای از داده ها انجام می شود پنهان می کنند. و آنها کار را برای بهینه ساز طرح پایگاه داده دشوار می کنند (گاهی اوقات غیرممکن) بهینه سازی پرس و جوهای حاصل را.
اگر از نما استفاده می کنید، نماهای دیگر را با آن پرس و جو نکنید. نماهای تودرتو باید “مسطح” و بازنویسی شوند تا فقط موارد مورد نیاز را بازیابی کنند.
اجرای عملیات بزرگ و چند جدولی در یک تراکنش
فرض کنید باید دادهها را از ۱۰ جدول به عنوان بخشی از عملیات حذف کنید. ممکن است وسوسه شوید که تمام حذفها را در تمام جداول در یک تراکنش اجرا کنید – اما این کار را نکنید. در عوض، عملیات هر جدول را جداگانه مدیریت کنید.
اگر نیاز دارید که حذفها در جداول به صورت اتمی انجام شوند، میتوانید آن را به بسیاری از تراکنشهای کوچکتر تقسیم کنید. به عنوان مثال، اگر ۱۰۰۰۰ ردیف دارید که نیاز به حذف در ۲۰ جدول دارند، می توانید هزار ردیف اول را در هر ۲۰ جدول در یک تراکنش حذف کنید، سپس هزار ردیف بعدی را در تراکنش دیگر و غیره. (این یکی دیگر از موارد استفاده خوب برای مکانیسم صف کار در منطق کسب و کار شما است، که در آن عملیاتهایی مانند این را میتوان مدیریت کرد، متوقف کرد و در صورت نیاز از سر گرفت.)
خوشهبندی در GUID یا سایر ستونهای “فرار”
GUIDها یا شناسههای منحصربهفرد جهانی، اعداد تصادفی ۱۶ بایتی هستند که برای دادن شناسههای متمایز به اشیا استفاده میشوند. بسیاری از پایگاه های داده آنها را به عنوان یک نوع ستون بومی پشتیبانی می کنند. اما آنها نباید برای خوشهبندی ردیفهایی که در آنها زندگی میکنند استفاده شوند. چون تصادفی هستند، باعث میشوند که خوشهبندی جدول به شدت تکه تکه شود. عملیات جدول می تواند خیلی سریع به مراتب کندتر شود. به طور خلاصه، در هیچ ستون هایی که تصادفی زیادی دارند، خوشه بندی نکنید. ستونهای تاریخ یا شناسه بهترین کار را دارند.
شمارش ردیف ها برای بررسی وجود داده
استفاده از عملیاتی مانند SELECT COUNT(ID) FROM table1
برای تعیین اینکه آیا برخی از دادهها در جدول وجود دارد یا نه، اغلب ناکارآمد است. برخی پایگاههای داده میتوانند به طور هوشمندانه عملیات SELECT COUNT()
را بهینه کنند، اما همه آنها این قابلیت را ندارند. اگر لهجه SQL شما آن را ارائه می دهد، رویکرد بهتر این است که از چیزی مانند IF EXISTS (انتخاب ۱ از جدول ۱ LIMIT 1) BEGIN ... END
استفاده کنید.
اگر تعداد ردیف مورد نظر شما باشد، روش دیگر این است که آمار تعداد ردیف را از جدول سیستم بدست آورید. برخی از فروشندگان پایگاه داده نیز پرس و جوهای خاصی دارند. به عنوان مثال، در MySQL، می توانید از SHOW TABLE STATUS
برای دریافت آمار در مورد همه جداول، از جمله تعداد ردیف ها استفاده کنید. با Microsoft T-SQL، رویه ذخیره شده sp_spaceused.
استفاده از محرکها
به همان اندازه که محرکها راحت هستند، محدودیت بزرگی دارند: آنها باید در همان تراکنشهای عملیات اصلی انجام شوند. اگر یک ماشه برای تغییر یک جدول ایجاد کنید، زمانی که جدول دیگری تغییر می کند، هر دو جدول قفل می شوند تا حداقل ماشه تمام شود. اگر باید از یک ماشه استفاده کنید، مطمئن شوید که منابع بیشتری از آنچه قابل تحمل است قفل نمی کند. یک رویه ذخیره شده ممکن است راه حل بهتری باشد زیرا می تواند عملیات ماشه مانند را در چندین تراکنش شکست دهد.
انجام جستجوهای منفی
پرس و جوهایی مانند SELECT * FROM Users WHERE Users.Status <> ۲
مشکل ساز هستند. یک نمایه در ستون Users.Status
مفید است، اما جستجوهای منفی مانند این معمولاً به اسکن جدول باز می گردند. راه حل بهتر این است که پرس و جوها را طوری بنویسید که از نمایه های پوششی به طور موثر استفاده کنند—برای مثال SELECT * FROM Users WHERE User.ID NOT IN (انتخاب Users.ID FROM USERS WHERE Users.Status=2)
. این به ما امکان میدهد از نمایهها در ستونهای ID
و Status
استفاده کنیم تا آنچه را که نمیخواهیم، بدون انجام اسکن جدول، حذف کنیم.
پست های مرتبط
SQL آزاد شده: ۷ اشتباه SQL که باید از آن اجتناب کرد
SQL آزاد شده: ۷ اشتباه SQL که باید از آن اجتناب کرد
SQL آزاد شده: ۷ اشتباه SQL که باید از آن اجتناب کرد