تور لحظه آخری
امروز : دوشنبه ، 5 آذر 1403    احادیث و روایات:  پیامبر اکرم (ص):ما قومى هستيم كه تا گرسنه نشويم غذا نمى‏خوريم و تا سير نشده‏ايم دست از غذا مى‏ك...
سرگرمی سبک زندگی سینما و تلویزیون فرهنگ و هنر پزشکی و سلامت اجتماع و خانواده تصویری دین و اندیشه ورزش اقتصادی سیاسی حوادث علم و فناوری سایتهای دانلود گوناگون شرکت ها

تبلیغات

تبلیغات متنی

صرافی ارکی چنج

صرافی rkchange

سایبان ماشین

دزدگیر منزل

تشریفات روناک

اجاره سند در شیراز

قیمت فنس

armanekasbokar

armanetejarat

صندوق تضمین

Future Innovate Tech

پی جو مشاغل برتر شیراز

لوله بازکنی تهران

آراد برندینگ

خرید یخچال خارجی

موسسه خیریه

واردات از چین

حمية السكري النوع الثاني

ناب مووی

دانلود فیلم

بانک کتاب

دریافت دیه موتورسیکلت از بیمه

طراحی سایت تهران سایت

irspeedy

درج اگهی ویژه

تعمیرات مک بوک

دانلود فیلم هندی

قیمت فرش

درب فریم لس

زانوبند زاپیامکس

روغن بهران بردبار ۳۲۰

قیمت سرور اچ پی

خرید بلیط هواپیما

بلیط اتوبوس پایانه

قیمت سرور dl380 g10

تعمیرات پکیج کرج

لیست قیمت گوشی شیائومی

خرید فالوور

بهترین وکیل کرج

بهترین وکیل تهران

خرید اکانت تریدینگ ویو

خرید از چین

خرید از چین

تجهیزات کافی شاپ

ویزای چک

محصولات فوراور

خرید سرور اچ پی ماهان شبکه

دوربین سیمکارتی چرخشی

همکاری آی نو و گزینه دو

کاشت ابرو طبیعی و‌ سریع

الک آزمایشگاهی

الک آزمایشگاهی

خرید سرور مجازی

قیمت بالابر هیدرولیکی

قیمت بالابر هیدرولیکی

قیمت بالابر هیدرولیکی

لوله و اتصالات آذین

قرص گلوریا

نمایندگی دوو در کرج

خرید نهال سیب

وکیل ایرانی در استانبول

وکیل ایرانی در استانبول

وکیل ایرانی در استانبول

 






آمار وبسایت

 تعداد کل بازدیدها : 1833671293




هواشناسی

نرخ طلا سکه و  ارز

قیمت خودرو

فال حافظ

تعبیر خواب

فال انبیاء

متن قرآن



اضافه به علاقمنديها ارسال اين مطلب به دوستان آرشيو تمام مطالب
archive  refresh

عمل صفحه بندیِ یک پایگاه داده بزرگ در برنامه های وب (Paging of Large Resultsets in ASP.NET)


واضح آرشیو وب فارسی:راسخون:
عمل صفحه بندیِ یک پایگاه داده بزرگ در برنامه های وب)Paging of Large Resultsets in ASP.NET(
عمل صفحه بندیِ یک پایگاه داده بزرگ در برنامه های وب (Paging of Large Resultsets in ASP.NET) مقدمه : عمل صفحه بندیِ یک پایگاه داده بزرگ در برنامه های وب مشکل شناخته شده ای است. بطور خلاصه شما نمی خواهید که همه ی نتایج درخواستتان در یک صفحه وب نشان داده شوند، پس نوعی ترتیب نمایش صفحه ای مناسب است. در حالیکه این کار در ASP ساده نبود. در کنترل DataGrid در ASP.NET این کار را بصورت چند خط کد، ساده میکند. پس PAGING در ASP.NET ساده است، ولی رفتار پیش فرضِ DataGrid به این شکل است که همه نتایج ثبت شده از درخواستهای شما از سرور SQL را دریافت و به برنامه ASP.NET فرستاده. اگر درخواست شما ملیونها رکورد را باز گرداند باعث مشکلات جدی در اجرا می شود. (اگر مطمئن نیستید، این درخواست را در برنامه وب اجرا کنید و اشغال شدن حافظه در قسمت ASP.NET_WP.EXE را در برنامه Taskmanager ملاحظه کنید). به همین خاطر راه کار PAGING هنگامیکه می خواهیم تنها ردیفها را از صفحه بگیریم نیاز است. مقالات و POSTهای زیادی در رابطه با این مشکل نوشته شده و چندین راه حل پیشنهاد شده. هدف در اینجا این نیست که روشی پیشنهاد کنیم که تمامی مسائل را حل کند، بلکه قصد داریم روشهای فعلی را بهبود بخشیم و برنامه آزمایشی طرح کنیم تا شما خود به تنهای آنرا ارزیابی کنید. این یک مقاله مفید برای شروع است که روشهای متفاوتی را توضیح و چندین نتیجه آزمایشی را شرح می دهد: چگونه از طریق Recordset صفحه بندی انجام دهیم : اولاً نیمی از روشها از ADO قدیمی استفاده می کنند و مخصوص ASP قدیمی نوشته شده اند. بقیه متدها روند ذخیره سرور SQL هستند. برخی از آنها زمان پاسخ ضعیفی بدست می آورند، همانطور که در پایین صفحه در نتایج اجرای مولف می بینید. ولی چند تا از آنها توجه مرا جلب کرده اند. Generalization: سه روشی که ما قصد دارم تا از نزدیک آنها را مورد برسی قرار دهم TempTable, DynamicSQL, Rowcount هستند. در ادامه متن من از روش دوم استفاده خواهم کرد که ASC-Desc نام دارد من فکر نمی کنم DynamicSQL نام خوبی بود، چون شما می توانید منطق DynamicSQL را به بقیه روشها اعمال کنید. مشکل عام در تمام این روشها این است که باید ارزیابی کنید که کدام ستون را برای تنظیم (SORTING) انتخاب می کند و به احتمال زیاد فقط ستون PK نیست. این مسئله باعث مشکلات جدیدی می شود، به این دلیل که برای هر درخواست که می خواهید از طریق PAGING نشان دهید باید به همان تعداد، درخواست PAGING بدهید. که تعداد مختلفی ستونهای مرتب دارید. این یعنی یا شما روش ذخیره متفاوت برای هر ستون (بدون توجه به روش PAGING استفاده شده) دارید یا باید آنرا به یک روش ذخیره با کمک Dynamic SQL تعمیم دهید. این کار اثر جزئی در اجرا دارد ولی اگر بخواهید تعداد زیاد درخواست از این طریق انجام دهید قابلیت نگهداری(maintainability) افزایش پیدا خواهد کرد. پس ما سعی می کنیم تا تمام روش های ذخیره شده در این متن را با Dynamic SQL تعمیم دهیم. ولی در برخی موارد این امکان وجود دارد تا به سطح خاصی از تعمیم برسیم، پس لازم است تا روشهای مجزا ذخیره را برای درخواستهای پیچیده بنویسیم. دومین مشکل با اجازه مرتب کردن ستونی از غیر ستون PK، در این است که اگر تنها آن ستونها به جهتی ایندکس نشده باشند، هیچ کدام از این متدها و روشها کارامد نخواهند بود. در تمام اینها اول باید یک منبع صفحه بندی ، مرتب شده باشد وهمانطور که می دانید، هزینه استفاده از مرتب سازی برای ستونهای None-indexed بسیار گزاف است. زمان پاسخ دهی آنقدر بالاست که تمامی پروسیجرها در این مورد در اصل بی فایده هستند. ( زمان پاسخ دهی از چند ثانیه به چند دقیقه بسته به اندازه جدول و زمان واکشی شروع رکورد، متغیر است). فهرستوار کردن (Indexing) برخی ستونها مشکلات اجرا بیشتری بوجود می آورند و ممکن است ناخواسته هم باشند. مثلاً این امکان وجود دارد که سرعت شما در شرایطی که Import های روزانه زیادی داشته باشید، پایین بیاید. TempTable : اولین موردی که روی آن بحث خواهم کرد متد temptable است. در حقیقت این یک روشی است که بسیار پیشنهاد می شود و من چندین با آن مواجه شدم. این مقاله دیگری است که به همراه مثال و توضیحات چگونگی استفاده از صفحه بندی با DataGrid را شرح می دهد : ASP.NET DataGrid Paging Part 2 - Custom Paging این متد در هر دو مقاله می تواند، بوسیله کپی کردن داده PK در temptable و بعد الصاق آن با درخواست های اصلی، بهبود پیدا کند .

این روش با کپی کردن ستونها به temptable بهبود پیدا می کند تا زمانیکه به آخرین ردیف برسیم (SELECT TOP EndRow…) ولی نکته اینجاست که در بدترین حالت - برای جدولی با یک میلیون رکورد شما یک میلیون رکورد در یک TempTable نیز خوهید داشت. با توجه به نکات و با توجه به نتایج مقاله بالا تصمیم گرفتیم تا این روش را از آزمایش خود حذف کنیم. Asc-Desc این متد از default ordering در subquery استفاده می کند و سپس reverse ordering را بکار می برد. دستور اینگونه است :



Full Code – Paging_Asc_Desc RowCount منطق اصلی این روش بر اساس اصطلاح SQL SET ROWCOUNT است تا هم از ردیفهای ناخواسته صرفه نظر کند وهم آنهایی که نیاز هستند را واکشی کند.

Full Code – Paging_RowCount SubQuery دو روش دیگر را نیز در نظر گرفته ام، و آنها از منابع مختلفی گرفته شده اند. اولی درخواست سه تایی معروف است با متد SubQuery.کاملترین روش، روشی است که در مقاله بعدی پیدا کردم. Server-Side Paging with SQL Server صفحه بندی از طرف سرور با استفاده از SQL Server : گرچه باید عضو شوید، ولی فایل a.zip با پروسیجرذخیره شده SubQuery موجود است. فایلِِ Listing_04.SELECT_WITH_PAGINGStoredProcedure شامل Dynamic SQL کامل است. من منطق کلی مشابه برای تمامی روشهای ذخیره شده در این متن استفاده کردم. در اینجا یک قاعده کلی به همراه لینکی به تمام پروسیجرها وجود دارد ( من کد اصلی را کمی کوتاه کردم، چون بخش شمارش رکوردها در هدف آزمایش من بی فایده بود).

Full Code – Paging_SubQuery Cursor من آخرین روش را هنگامیکه در google می گشتم پیدا کردم، شما می توانید رشته اصلی را در اینجا پیدا کنید. این روش از cursor پویای طرف سرور استفاده می کند. بسیاری از مردم از cursor هایی که قابلیت اجرای ضعیف دارند به دلیل طبیعت غیر وابسته و طبیعت ترتیبی آنها دوری می کنند. مسئله این است که صفحه بندی یک کار ترتیبی است و از هر متدی که استفاده کنید باید به شکلی به ردیف شروع باز گردید. در تمامی روشهای پیشین با انتخاب تمامی ردیف ها قبل از ردیف شروع به علاوه ردیف مورد نظر این کار انجام می شود، که پس از آن تمام ردیفهای قبل حذف می شوند. Dynamic cursor قابلیت FETCH RELATIVE را دارد که پرش جادویی انجام می دهد. منطق اصلی اینگونه است :

Full Code – Paging_Cursor Generalization of Complex Queries : تعمیم درخواستهای پیچیده : همانطور که قبلاً اشاره شده همه روشها با Dynamic SQL تعمیم داده می شوند. پس در تئوری ، آنها می توانند با تمام درخواستهای پیچیده کار کنند. این یک نمونه درخواست پیچیده ای است که با پایگاه داده Northwind کار می کند.



فراخوانی پروسیجر Paging که صفحه دوم را باز می گرداند شبیه به این است :



توجه داشته باشید در درخواست اصلی، نامهای مستعار در عبارتOrderby استفاده می شوند و نمی توانید در روش Paging این کار را انجام دهید، چون وقتگیرترین کار در بین همه اینها پرش از ردیفهای قبل به ردیف اول است. این از روش های مختلفی انجام می شود ولی قانون این نیست که همه فیلدهای لازم را از اول واکشی کنید و فقط ستونهای PK باید واکشی شوند (در زمانی که از متد RowCount استفاده می شود، ستونها مرتب واکشی می شوند) که سرعت این کار را بالا می برند. تمام فیلدهای مورد نیاز فقط برای ردیفهای که مطعلق به صفحه درخواست شده هستند واکشی می شوند. بنابراین نامهای مستعار فیلدها تا آخرین درخواست وجود ندارند و ستونهای مرتب، باید زودتر استفاده شوند ( در درخواستهای پرش ردیف. row skipping queries). مشکل دیگر روش Rowcount این است که آن، طوری تعمیم یافته که فقط با یک ستون درعبارت ORDER BY کار می کند. همینطور برای روش های Asc-Desc و Cursor، اگرچه می توانند با چند ستون مرتب کار کنند، ولی نیاز است تا فقط یک ستون در PK وجود داشته باشد. حدس می زنم که این با Dynamic SQL بیشتری حل شود، ولی به نظر من ارزشی ندارد.گرچه این شرایط احتمال وقوع زیادی دارند ولی خیلی عادی نیستند. حتی اگر هم باشند، شما همیشه می توانید یک پروسیجر جداگانه Paging، با دنبال کردن قانونهای بالا بنویسید. Performance Testing تست اجرا : من این چهار روش را در آزمایشاتم بکار بردم، اگر شما روش بهتری دارید خوشحال می شوم درباره آن بدانم. علیرغم این می خواستم این روشها را مقایسه کنم و کیفیت آنها را اندازه گیری کنم. اولین فکر این بود که یک برنامه کاربردی تست Asp.net با صفحه بندی dataGride بنویسم و سپس پاسخ صفحه (page Response)را اندازه گیری کنم . با این حال مدت زمان پاسخ را در روش های ذخیره نشان نمی دهد. پس برنامه Consol، به نظر مناسب تر می رسید. همچنین من یک برنامه کاربردی وب نه برای تست اجرا بلکه به عنوان مثال، که چگونه صفحه بندی معمولِ datagride با این روشهای ذخیره شده کار می کند، را نیز استفاده کرده ام. که هر دوی آنها از راه حل Paging Test استفاده شده اند. من از جدولی که بطور خودکار تولید شده (auto Generated) استفاده کردم و تقریباً 500000 رکورد را در آن وارد کرده ام. اگر شما جدول بزرگی ندارید تا با آن آزمایش کنید، می توانید از طرح جدول ما و پروسیجرهای ذخیره شده برای Generate کردن دادها استفاده کنید. من یک ستون ID برای PK نمی خواستم، پس در عوض از uniqueidentifier استفاده کردم. اگر از این متن استفاده کنید شاید بخواهید بعد از ساختن جدول به آن شناسه یا ID اضافه کنید. اعدادی که با Pk به ترتیب شده اند را اضافه کنید و شما نشانه ای دارید که زمانیکه از روش Paging با ترتیب PK استفاده می کنید، صفحه صحیح واکشی شده است. نظر به اینکه performance testing بر طبق آن بود، به این شکل است که، پروسیجر خاصِ ذخیره را به دفعات زیاد از طریق حلقه صدا می زنیم و میانگین زمان پاسخ را اندازه گیری می کنیم. همینطور برای اینکه خطا و انحراف Cache را حذف کنیم و بخاطر اینکه شرایط واقعی را به طور دقیق نشان دهیم- چندین فراخوانی، به یک پروسیجر ذخیره با صفحه مشابهِ واکشی شده ، بنظر کار نامناسبی است. پس به، ترتیب تصادفی از روش ذخیره شده مشابه، با تعداد صفحه های متفاوت نیاز داریم. درک این مساله که، زمان پاسخ به فاصله ای که صفحه واکشی شده از مکان شروع Resultset بستگی دارد، موضوع چندان پیچیده ای نیست. هرچه رکورد شروع دورتر باشد از رکوردهای بیشتری باید پرش کنیم. و به همین دلیل من 20 صفحه اول را در شکل نگذاشتم. در عوض از 2N سری صفحه استفاده کردم، ضمناً یک حلقه 1000 تایی هم تنظیم شده است. پس تقریباً هر صفحه حدوداً 1000 بار واکشی شد. نتیجه : اینها نتایجی است که من بدست آوردم. Paging_Results (MS Excell file)









نتیجه کلی : روشها با ترتیب، از بهترین به این شکل اجرا شده اند، Subquery, Asc-Desc ,Cursor, RowCount . رفتار در بخشهای پایین تر خیلی جالب بود، چون در بسیاری از مواقع، شما به ندرت بیشتر از پنج صفحه اول را جستجو می کنید، پس روش subquery می تواند نیازهای شما را در این مورد تآمین کند. اینها همه به اندازه Resultset ، و پیش بینی اینکه هر چند وقت یکبار صفحات دور واکشی می شوند، بستگی دارند. شما می توانید از ترکیبی از روشها نیز استفاده کنید. خود من تصمیم گرفتم تا از متد Rowcount در هر جایی که ممکن است استفاده کنم. که این روش حتی برای صفحه اول هم بخوبی کار می کند. منظور از "هرجایی که ممکن است " این است که برای مواردی که تعمیم دادن این روش مشکل است، خود من از روش Cursor استفاده می کنم ( احتمالاً به همراه Subquery برای چند صفحه اول). دلیل اصلی نوشتن این مقاله این بود که من از طرف انجمن برنامه نویسی حمایت می شدم. تا چند هفته دیگر هم من روی یک پروژه جدید کار می کنم. تحقیقات اولیه نشان داد که جدولهای بزرگی وجود دارد و این جدولها در درخواستهای مشترکِ پیچیده مورد استفاده قرار خواهند گرفت و نتایج آنها در برنامه های کاربردی ASP.NET نشان داده خواهد شد (به همراه مرتب سازی و صفحه بندی). به همین دلیل من وقت زیادی برای تحقیق و پیدا کردن بهترین روش Paging صرف کردم و فقط کیفیت اجرا برای من مهم نبود بلکه استفاده و نگهداری آن نیز جالب بود. هم اکنون نتیجه ای که صرف این تحقیقات کردم را می گیرم. شما می توانید در پایین یک پست از طرف C. v. Berkel ببینبد که یک ایراد از روش Rowcount گرفته، که این روش زمانی که ستون منحصر به فرد و Unique نباشد جواب نخواهد داد. روش Rowcount در آزمایش من بهترین پاسخ را داشت ولی الان واقعاً در نظر دارم اصلاً از آن استفااده نکنم. در اکثر موارد بترتیب کردن ستونها (بجز ستون PK) منحصربه فرد نیست، که باعث می شود روش Cursor که سریعترین و قابل اجراترین روش در اکثر شرایط است انتخاب کنم که می تواند با روش Subquery برای چند صفحه اول استفاده شود و احتمالاً از روش Rowcount در ستونهای منحصربه فرد مرتب . مورد دیگر که ذکرآن پر ارزش است، ضعف روش ASC-Desc است. همیشه برای چند صفحه آخر تعداد PageSize رکوردهای را برمی گرداند و نه تعداد حقیقی را ( که احتمال دارد کمتر از Pagesize باشد). تعداد صحیح قابل شمارش است ولی از آنجاییکه که قصد ندارم از این روش استفاده کنم (بخاطر نحوه اجرای آن ) پس نیازی به گسترش بحث نیست. معرفي سايت مرتبط با اين مقاله تصاوير زيبا و مرتبط با اين مقاله





این صفحه را در گوگل محبوب کنید

[ارسال شده از: راسخون]
[مشاهده در: www.rasekhoon.net]
[تعداد بازديد از اين مطلب: 658]

bt

اضافه شدن مطلب/حذف مطلب







-


گوناگون

پربازدیدترینها
طراحی وب>


صفحه اول | تمام مطالب | RSS | ارتباط با ما
1390© تمامی حقوق این سایت متعلق به سایت واضح می باشد.
این سایت در ستاد ساماندهی وزارت فرهنگ و ارشاد اسلامی ثبت شده است و پیرو قوانین جمهوری اسلامی ایران می باشد. لطفا در صورت برخورد با مطالب و صفحات خلاف قوانین در سایت آن را به ما اطلاع دهید
پایگاه خبری واضح کاری از شرکت طراحی سایت اینتن