View Full Version : سوال: استفاده از بانک اطلاعاتی با حجم بالا
Mask
سه شنبه 30 آذر 1389, 19:44 عصر
با سلام
من بانک اطلاعاتی دارم که حدود 15 میلیون رکورد داره و زمانی که برنامه میخاد بیاد بالا یه چند ثانیه ای طول میکشه.
چیکار باید کرد که هم برنامه زود بیاد بالا و هم بانک کامل در برنامه لود بشه؟
ممنون.
ghabil
سه شنبه 30 آذر 1389, 20:00 عصر
هیچ وقت اول برنامه جدولهات رو باز نکن، و تقریبا هیچ وقت نیاز نخواهی داشت که اینهمه دیتا رو اصلا لود بکنی، همیشه سعی کن فقط در زمان نیاز با کوئری های آپتیمایز شده فقط همونقدر اطلاعات که لازم داری رو لود کنی و تا کارت هم تموم شد جداول رو ببندی.
Mask
سه شنبه 30 آذر 1389, 20:37 عصر
ممنون.
ای که وگفتی یعنی چه؟:قلب:
کوئری های آپتیمایز شده
و اگه بخام دیتا هام رو در گزید نشون بدم باید چیکار کنم؟
Felony
سه شنبه 30 آذر 1389, 21:36 عصر
میتونی ADOTable یا ADOQuery ت رو تو یه Thread جداگانه بسازی و ازش استفاده کنی .
ghabil
سه شنبه 30 آذر 1389, 22:18 عصر
کوئری آپتیمایز شده میتونه تعریفش از خیلی ساده تا خیلی پیشرفته باشه: حالا از سادش که بخوایم شروع کنیم مثلا به این اشتباه وحشتناک بسیار مصطلح میتونم اشاره بکنم که زیاد دیدم وقتی یک نفر میخواد یک سطر اطلاعات رو زا یک بانک بخونه اول یک Select میزنه کل اطلاعات رو میخونه بعد دوباره میره روی اطلاعات لود شده مثلا لوکیت میکنه ، یا در حالیکه فقط مقادیر یک ستون رو میخواد سلکت ستاره میزنه و تمام ستونها رو میخونه! باور کردنی نیست ولی برنامه حرفه ای نسبتا معروفی رو دیدم که سلکت ستاره میزند و کل یک جدول رو که بعضی وقتها حدود 500 هزار تا رکورد داشت رو باز میکرد، بعد میرفت روش Locate میکرد که مقدار یک فیلد رو بخونه. یعنی کاری که در صدم ثانیه با اشغال چند بایت حافظه میشد انجام داد رو تبدیل میکرد به یک کار که چندین ثانیه طول میکشید و در حد گیگابایت حافظه اشغال میکرد!
یا مثلا هیچ وقت کاربر تو لازم نداره 10000 تا رکورد رو براش لود کنی که ببینه، همیشه اگر دیتاها رو درست سورت کنی، همون 100 تا رکورد اول بیشتر از کافیه، اگر چیزی که میخواست نبود شرایط و سورت رو عوض میکنه 100 تا دیگه لود میکنی و به همین ترتیب....
behzadboloori
چهارشنبه 01 دی 1389, 08:25 صبح
میتونی ADOTable یا ADOQuery ت رو تو یه Thread جداگانه بسازی و ازش استفاده کنی .
میشه در این مورد یه کم عملی توضیح بدین. یعنی باید چطوری کدنویسی کنم؟
vcldeveloper
چهارشنبه 01 دی 1389, 16:02 عصر
میشه در این مورد یه کم عملی توضیح بدین. یعنی باید چطوری کدنویسی کنم؟
در همچین سناریویی اون کار ارزش نداره و پاک کردن صورت مسئله هست. چون برنامه نویس باید بدونه که 15 میلیون رکورد یک جا به درد کاربر نمیخوره، مگه اینکه بخواد از همه این رکورد ها گزارش تهیه کنه. در اون صورت هم وجود یک سرور گزارش ساز بهتر از این هست که هر کدوم از کلاینت ها برای خودشان 15 میلیون رکورد از بانک بگیرند و ازش گزارش تولید کنند.
در هر حال، اگر مشکل فقط فریز شدن برنامه در زمان اجرای کوئری هست، می تونید اون کوئری را به صورت Asynchronous اجرا کنید، با این کار، ADO خودش کوئری رو در Thread جداگانه ایی اجرا میکنه. اما باید دقت کنید که تا زمان پایان اجرای کوئری، نتایج کوئری در دسترس شما نیست، و نباید در اون زمان به کاربر اجازه بدید که با اون داده ها کاری انجام بده.
Mask
چهارشنبه 01 دی 1389, 18:43 عصر
ممنون.
میشه در مورد این روش توضیح بیشتری بدید.
به صورت Asynchronous
behzadboloori
پنج شنبه 02 دی 1389, 08:34 صبح
در هر حال، اگر مشکل فقط فریز شدن برنامه در زمان اجرای کوئری هست، می تونید اون کوئری را به صورت Asynchronous اجرا کنید، با این کار، ADO خودش کوئری رو در Thread جداگانه ایی اجرا میکنه. اما باید دقت کنید که تا زمان پایان اجرای کوئری، نتایج کوئری در دسترس شما نیست، و نباید در اون زمان به کاربر اجازه بدید که با اون داده ها کاری انجام بده.
من از در کوئری Execute Option را برابر Asynchronous قرار دادم. آیا مد نظر شما همین بود؟
التبه این کار رو برای این انجام دادم که دستورات OnFetchProgress آجرا بشه و بتونم پیشرفت دریافت اطلاعات از بانک رو نشون بدم. با وجود اینکه CacheSize رو برابر یک قرار دادم ولی باز هم فقط دوبار این دستور اجرا شد. و هیچ کوئری همزمان هم اجرا نشد. پس نمیتونه که در Thread های جداگانه اجرا شده باشه؟ آیا درست میگم؟
vcldeveloper
پنج شنبه 02 دی 1389, 17:33 عصر
من از در کوئری Execute Option را برابر Asynchronous قرار دادم. آیا مد نظر شما همین بود؟
بله،
با وجود اینکه CacheSize رو برابر یک قرار دادم ولی باز هم فقط دوبار این دستور اجرا شد. و هیچ کوئری همزمان هم اجرا نشد.
وقتی کد شما برای رویداد OnFetchProgress اجرا شد، یعنی در Thread جداگانه ایی اجرا شده. اگر کوئری در همون Thread اصلی برنامه شما اجرا میشد، تا زمان پایان اجرای کوئری، کدی از برنامه شما اجرا نمیشد. واژه Asynchronous هم برای همین برای این نوع از عملیات به کار رفته.
behzadboloori
پنج شنبه 02 دی 1389, 20:56 عصر
وقتی کد شما برای رویداد OnFetchProgress اجرا شد، یعنی در Thread جداگانه ایی اجرا شده. اگر کوئری در همون Thread اصلی برنامه شما اجرا میشد، تا زمان پایان اجرای کوئری، کدی از برنامه شما اجرا نمیشد. واژه Asynchronous هم برای همین برای این نوع از عملیات به کار رفته.
آیا به ازای هر رکورد لود شده باید OnFetchProgress یک بار اجرا شود؟
اگر اینطور است چرا من با 500 رکوردی که لود میکنم فقط دوبار اجرا میشود؟
یعنی اگر درون OnFetchProgress یک کانتر بذارم همیشه عدد 2 رو نشون میده.
vcldeveloper
جمعه 03 دی 1389, 00:20 صبح
آیا به ازای هر رکورد لود شده باید OnFetchProgress یک بار اجرا شود؟
جایی در مستندات ADO یا راهنمای دلفی اشاره نشده که OnFetchProgress به ازاء هر رکورد یک بار فراخوانی میشه. همچنین در این مستندات جایی اشاره نشده که تغییر مقدار CacheSize تاثیری در تعداد فراخوانی OnFetchProgress داره. OnFetchProgress صرفا مکانیزمی برای تعیین پیشرفت اجرای کوئری هست، و داده های لازم برای محاسبه این پیشرفت را هم خودش به شما میده، یعنی هم مجموع رکوردها را به شما میده، و هم مجموع رکوردهای دریافت شده را به شما میده، در نتیجه می تونید به راحتی با داشتن این دو عدد، میزان پیشرفت عملیات را محاسبه کنید.
behzadboloori
جمعه 03 دی 1389, 12:23 عصر
جایی در مستندات ADO یا راهنمای دلفی اشاره نشده که OnFetchProgress به ازاء هر رکورد یک بار فراخوانی میشه. همچنین در این مستندات جایی اشاره نشده که تغییر مقدار CacheSize تاثیری در تعداد فراخوانی OnFetchProgress داره.
این رو من توی Help برنامه پیدا کردم
The command fetches remaining rows after the initial quantity specified in the Cache property asynchronously.
The dataset first fetches the number of records specified by the CacheSize property synchronously, then fetches any remaining rows asynchronously.
با این مستندات که در راهنمای دلفی وجود داره فکر میکنم که در صورتی که CacheSize=1 باشد باید به ازای هر رکورد OnFetchProgress یکبار اجرا بشه. درست میگم یا برداشتم اشتباهه؟
vcldeveloper
جمعه 03 دی 1389, 17:36 عصر
The dataset first fetches the number of records specified by the CacheSize property synchronously, then fetches any remaining rows asynchronously.
این عبارات فقط میگن به اندازه تعداد رکورد مشخص شده در CacheSize، رکوردهایی به صورت Synchronous دریافت میشند، و بعد از اون، سایر رکوردها به صورت Asynchronous دریافت میشند.
behzadboloori
شنبه 04 دی 1389, 08:01 صبح
این عبارات فقط میگن به اندازه تعداد رکورد مشخص شده در CacheSize، رکوردهایی به صورت Synchronous دریافت میشند، و بعد از اون، سایر رکوردها به صورت Asynchronous دریافت میشند.
اگر اینطور که شما میگین باشه باید در بار دومی که رکوردها رو میگیره، یکی یکی بره جلو و بعد از هر رکورد یکبار OnFetchProgress رو اجرا کنه (البته اگر CacheSize برابر یک باشه) درسته؟
vcldeveloper
شنبه 04 دی 1389, 13:23 عصر
اگر اینطور که شما میگین باشه باید در بار دومی که رکوردها رو میگیره، یکی یکی بره جلو و بعد از هر رکورد یکبار OnFetchProgress رو اجرا کنه (البته اگر CacheSize برابر یک باشه) درسته؟
گفتم، من در راهنمای دلفی و راهنمای ADO مطلبی ندیدم که به این موضوع اشاره کنه. خودم هم فرصت نکردم شخصا تست کنم.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.