PDA

View Full Version : سوال: كند شدن برنامه با استفاده از table زياد



ariobarzan
دوشنبه 30 دی 1387, 07:17 صبح
با سلام
در برنامه اي مشغول تهيه اون هستم تعداد فرم ها زياده و همين طور تعداد جدول هاي مورد استفاده شده.
امكان كمتر شدن فرم ها و جدول ها نيز بيشتر از اين وجود نداره.
مشكل اينه كه برنامه كند شده .
هر فرم كه نمايش داده ميشه جدول را open و موقع hide شدن اون را Close كردم باز هم مشكل حل نشد.
اكثر ارتباط با بانك از طريق query ها انجام ميشه كه اون ها رو هم موقع نياز باز و بسته
مي كنم .
تعداد ركورد ها در بزرگترين جدول با ده تا فيلد عمدتا از نوع Nvarchar زير پنجاه هزار ركورد هست
عكس ها ي پرسنلي افراد در جدول جداگانه ذخيره شدند .(حدود چهار هزار ركورد )

راه حل هاي پيشنهادي شما جهت رفع كندي برنامه چيه؟

bmanfy
دوشنبه 30 دی 1387, 09:03 صبح
چرا هی باز کنی و ببندی .
یک بار باز کن تا انتهای برنامه . چون باز کردن و بستن منجر مثل اینه که دوباره واکشی کنی . و در کل با افزایش حجم اطلاعات این روند کند تر میشه .
برای جدولی هم مثل اون عکسهایی که داری هیچ وقت سعی نکن کل اطلاعاتش رو واکشی کنی ، تنها اون رکوردی رو واکشی کن که نیاز داری و با یک Where هم حل میشه . و طوری هم هست که هیچ وقت این نیاز نیست که کلیه عکسها لازم باشه .
برای اینکه در اول شروع برنامه ات هم سرعت اجرا بالا باشه در ابتدا نیاز نیست کل فرمها ساخته بشه . به عبارتی هر وقت که لازمه بساز .
و ....
البته اگه اشتباه نکنم در جایی از همین سایت گفته بودند که AdoTable از AdoQuery بهتره . البته درست یادم نیست فقط یه لایه از خوانده های گذشته توی ذهنم هست .
البته همه جا هم نمیشه از AdoTable استفاده کرد .
موفق باشی .

vcldeveloper
دوشنبه 30 دی 1387, 11:58 صبح
البته اگه اشتباه نکنم در جایی از همین سایت گفته بودند که AdoTable از AdoQuery بهتره .
صحت نداره.

ariobarzan
دوشنبه 30 دی 1387, 12:51 عصر
با تشكر از توجه شما

1- آيا باز كردن همه جداول در ابتداي برنامه باعث اشغال حافظه و كند شدن نميشه؟
2- ساختن فرم ها چطور؟
3- من يك فرم اصلي دارم كه روي صفحه 12 Botton قرار دادم كه هر كدوم يك فرم ديگه را فعال مي كنه و در فرم هاي دوم هم botton هايي كه به فرم ديگه وصل ميشه .
( تا چهار لايه)
آيا اگر از حالت botton به حالت منويي تغيير كنه تاثيري در رفع كندي داره يا نه؟

دنیای دلفی
دوشنبه 30 دی 1387, 14:56 عصر
پاسخ 1 : خير نميشه چون باز كردن جداول به معني اين نيست كه كليه ركوردها به حافظه منتقل شده اند .
2-ساختن فرم تاثير خاصي روي سرعت برنامه نداره
3-مطمئن باش اينها ربطي به كند شدن برنامه شما نداره .

شايد مشكل كند شدن برنامه شما اين باشه كه يك Query باز را رها كرده اي و خاصيت MasterSource آن را به يك جدول وصل كرده اي و وقتي در فرمهاي ديگر هستي اون Query مرتبا به روز مي شه و خود به خود سرعت عملكرد برنامه شما پايين مي آيد .

پيشنهاد : كليه فرمهاي برنامه را غير فعال كن و شروع كن يكي يكي فعال كردنشون ببين با اضافه شدن كدوم فرم سرعت برنامه به طور محسوس كاهش مي يابد .

بعد بررسي كن مشكل از چيست .
تا بعد

vcldeveloper
دوشنبه 30 دی 1387, 16:23 عصر
پاسخ 1 : خير نميشه چون باز كردن جداول به معني اين نيست كه كليه ركوردها به حافظه منتقل شده اند .
دقیقا برعکس! وقتی جدولی باز میشه، بلافاصله رکورهای آن به حافظه کلاینت منتقل میشند.

دنیای دلفی
دوشنبه 30 دی 1387, 22:15 عصر
دقیقا برعکس! وقتی جدولی باز میشه، بلافاصله رکورهای آن به حافظه کلاینت منتقل میشند.فكر نمي كنم براي همه بانكها همچين اتفاقي بيافتد من يك بانك دارم با حجم 900 مگابايت و تعداد سه ميليون ششصد هزار ركود باز و بسته شدن آن به سادگي و سرعت يك جدول 200 ركوردي است البته بانكم DBISAM است . اگر قرار بود كليه ركوردها در حافظه لود بشن بعد از باز شدن جدول كه دهن حافظه سرويس مي شود تازه نكته مهم تر كه مطمئن هستم فقط بخش كوچكي از ركوردها در رم مي رود اين است كه وقتي در شبكه به صورت Client Server اقدام به استفاده از اين بانك در Client مي كنم فقط چند ثانيه باز شدن جدول 900 مگابايتي طول مي كشد . ولي وقتي در مثلا DBGrid اقدام به حركت به سمت ركوردهاي پايين تر مي كنم كاملا مشخص است كه در هنگام پايين رفتن دارد اطلاعات جديد را در رم لود مي كند خوب كاملا مشخص مي شه كه كليه اطلاعات در هنگام باز شدن بانك به حافظه كلاينت منتقل نمي شود .

اگر درست نيست توضيح تخصصي بدهيد .

vcldeveloper
سه شنبه 01 بهمن 1387, 02:24 صبح
البته بانكم DBISAM است .
این قابلیتی هست که DBISAM کامپوننت (به عنوان یک کامپوننت تجاری 3rd Party) خودش ایجاد کرده تا رکوردها را بصورت بخش به بخش واکشی کنه. این قابلیت بطور پیش فرض در کامپوننت های استاندارد دسترسی به داده دلفی وجود نداره، به غیر از ClientDataset که در صورت اتصال به DatasetProvider در سمت سرور، گزینه ایی برای FetchOnDemand داره.

bmanfy
سه شنبه 01 بهمن 1387, 09:51 صبح
صحت نداره


اتفاقا یادمه این رو هم خودتون گفته بودید . حالا دوباره نگاه میکنم شاید من اشتباه کرده باشم. به هر حال .



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

در ضمن اطلاعاتی هم که فکر میکنی به ندرت مورد استفاده قرار میگره جدولشون رو جدا کن و با یک کلید به جدول اصلی نسبت بده .

ariobarzan
سه شنبه 01 بهمن 1387, 12:42 عصر
ضمن تشكر از توجه دوستان
در مورد اينكه برنامه با استفاده از فرم هاي مختلف و Botton هاي روي اين فرم ها كار كنه يا بصورت منو در يك فرم ديده بشه نظري نداريد؟
بجز تاثير احتمالي روي سرعت ، از نظر شكل ظاهري برنامه كدوم يكي بهتر و متداول تره؟
ضمنا اگه من همه جا از query استفاده كنم بجاي بازو بسته كردن جدول امكان پذيره؟

bmanfy
سه شنبه 01 بهمن 1387, 17:57 عصر
بجز تاثير احتمالي روي سرعت ، از نظر شكل ظاهري برنامه كدوم يكي بهتر و متداول تره؟

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



ضمنا اگه من همه جا از query استفاده كنم بجاي بازو بسته كردن جدول امكان پذيره؟

من که دقیق منظورتون رو نفهمیدم .
اما مثلا با AdoQuery استفاده کنی به نظر من انعطاف پذیرتره .
و در ضمن در مواقعی برای Refresh کردن میتونی از Reduery استفاده کنی که هزینه ی چندانی در مقابل open/Close نداره .

vcldeveloper
چهارشنبه 02 بهمن 1387, 02:05 صبح
اما مثلا با AdoQuery استفاده کنی به نظر من انعطاف پذیرتره .
و در ضمن در مواقعی برای Refresh کردن میتونی از Reduery استفاده کنی که هزینه ی چندانی در مقابل open/Close نداره
Requery در ADO معادل همون باز و بسته کردن دیتاست هست، و برتری بر آن نداره

ariobarzan
چهارشنبه 02 بهمن 1387, 07:55 صبح
برنامه يك برنامه پرسنلي و صدور كارته
ضمنا من بجاي باز كردن جدول عكس ، از adoquery استفاده كردم كه فوق العاده روي سرعت برنامه تاثير گذاشت و تا حدود زيادي مشكلم حل شد .

در مورد ظاهر برنامه شخصا علاقه دارم كه از فرم ها و Botton بجاي منو استفاده كنم و تا حالا كه كاربران اعتراضي نداشتند. ولي ميخواستم بدونم كدوم يكي عرف تره و مزايا و معايب اونها رو از نظر برنامه نويسي بدونم.

از توجه شما ممنونم

bmanfy
چهارشنبه 02 بهمن 1387, 17:41 عصر
Requery در ADO معادل همون باز و بسته کردن دیتاست هست، و برتری بر آن نداره

من خودم جدولی دارم که 70 تا فیلد داره و زمانی که میخوام باز بسته کنم خیلی کند انجام میشه . اما با Requery به شدت این مدت زمان کاهش یافته .
هر چند از نظری فنی و اینکه کارش دقیقا نمی دونم به چه صورته اما به جرات میتونم بگم خیلی سریعتره .

bmanfy
چهارشنبه 02 بهمن 1387, 18:09 عصر
در مورد ظاهر برنامه شخصا علاقه دارم كه از فرم ها و Botton بجاي منو استفاده كنم و تا حالا كه كاربران اعتراضي نداشتند. ولي ميخواستم بدونم كدوم يكي عرف تره و مزايا و معايب اونها رو از نظر برنامه نويسي بدونم.


خوب من خودم هم تا به حال خیلی کم از منو توی برنامه ها م استفاده کردم . و در بیشتر برنامه ها که دیدم . دکمه عرف تر هست .
دکمه خوانایی برنامه را هم بالا میبره . اما خوب منو چو تودرتو و گزینه های اون پنهانه یع مقدار خوانا نیست و ممکنه بسیاری از کارها رو کاربر نتونه با منو انجام بده . حالا به هر دلیلی .

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

اما خوب در کل برای کاربر عرف ویندوزه . یعنی در واقع برنامه ای رو بیشتر با اون راحتتره که شبیه ویندوز باشه .
حالا نه از همه لحاظ . مثلا ببین تو ویندوز F1 معادل Help هست و تو برنامه ها شما سعی میکنی از F1 استفاده کنی برای بخش کمک یا راهنما چون میدونی که برای کاربران هم آشنا تره . و به مراتبط دردیگر چیزها .

اما خوب یه چیزی هم که هست نباید برنامه ات رو زیاد شلوغ کنی . کاربران بیشتز ساده پسندند .
http://barnamenevis.org/forum/showthread.php?t=97905
این مقاله رو بخون . در بخش مقالات سایت پیداش کردم .

vcldeveloper
پنج شنبه 03 بهمن 1387, 01:21 صبح
من خودم جدولی دارم که 70 تا فیلد داره و زمانی که میخوام باز بسته کنم خیلی کند انجام میشه . اما با Requery به شدت این مدت زمان کاهش یافته .

Use the Requery method to refresh the entire contents of a Recordset object from the data source by reissuing the original command and retrieving the data a second time. Calling this method is equivalent to calling the Close (http://www.barnamenevis.org/forum/mdmthclose.htm) and Open (http://www.barnamenevis.org/forum/mdmthrstopen.htm) methods in succession. If you are editing the current record or adding a new record, an error occurs.



این مربوط به راهنمای ADO هست.

bmanfy
پنج شنبه 03 بهمن 1387, 10:11 صبح
طبق برداشت سریعی که من از متن بالا داشتم اظهار داشته که تنها رکوردهای جدید رو واکشی میکنه . و کل اطلاعات رو مجدد واکشی نمیکنه و نتیجه ای که در نهایت حاصل میشه شبیه به Open , Close است .
البته در ترجمه ی بعضی از کلمات مشکل داشتم .
حالا باز هم میرم بیشتر و دقیق تر معنیش میکنم .
یه وقت مثل بعضی از دوستان دیگه از اینکه نظرم رو میگم ناراحت نشید . چون به هر حال من هم حق دارم از حرفم دفاع کنم .میشه شما هم در عمل اون رو بررسی کنید با یه جدول بزرگ . چون در یه جدول کوچک تفاوت سرعت محسوس نیست . چون من خودم در چنین شرایطی به تفاوت سرعت با Requery پی بردم .

ممنون .

vcldeveloper
پنج شنبه 03 بهمن 1387, 11:57 صبح
طبق برداشت سریعی که من از متن بالا داشتم اظهار داشته که تنها رکوردهای جدید رو واکشی میکنه . و کل اطلاعات رو مجدد واکشی نمیکنه و نتیجه ای که در نهایت حاصل میشه شبیه به Open , Close است .
البته در ترجمه ی بعضی از کلمات مشکل داشتم .خیر، این برداشت از متن بالا درست نیست...


Use the Requery method to refresh the entire contents of a Recordset objectاز Requery برای دوباره پر کردن تمام محتوای یک شی Recordset (شی Recordset در ADO تقریبا معادل همان Dataset در دلفی هست) استفاده کنید...



from the data source by reissuing the original command and retrieving the data a second time.از منبع داده از طریق فراخوانی مجدد فرمان (منظور دستور SQL هست) اولیه، و دریافت داده ها برای بار دوم.
[یعنی دستور SQL مجددا به سرور فرستاده میشه، و نتیجه آن هر چی که باشه، مجددا از سرور به کلاینت منتقل میشه]


Calling this method is equivalent to calling the Close (http://www.barnamenevis.org/forum/mdmthclose.htm) and Open (http://www.barnamenevis.org/forum/mdmthrstopen.htm) methods in succession.اجرای این متد معادل فراخوانی متدهای Close و Open به ترتیب هست. [وقتی Close فراخوانی میشه، رکوردست موجود حذف میشه، و وقتی Open فراخوانی میشه، فرمان SQL مجددا به سرور ارسال میشه، و یک رکوردست جدید از سرور دریافت میشه]


If you are editing the current record or adding a new record, an error occursاگر (در هنگام فراخوانی این متد) در حال ویرایش رکورد جاری، یا ایجاد رکورد جدید باشید، یک خطا واقع می شود. [برای همین هم در کامپوننت های ADO دلفی قبل از فراخوانی Requery، یک بار CheckBrowseMode فراخوانی می شود، تا مطمئن شوند رکوردی در حالت Edit یا Insert قرار ندارد.]

bmanfy
جمعه 04 بهمن 1387, 09:04 صبح
با وجود این همه چیز که گفتید یه سوال پیش میاد چه دلیلی داره دوتا دستور مشابه تعرف بشه . بی شک تفاوتهایی باید با همدیگه داشته باشند ؟:متفکر:
و از طرفی دوباره هم روی برنامه خودم تست کردم خیلی سرعتش با Close, Open فرق میکنه .
بزارین برنامه رو براتون توضیح بدم
من تو برنامه ام یک AdoQuery دارم که بنا به دلایل خاص اون رو به جداول مختلف برای ثبت اطلاعات وصل میکنم . و یک AdoQuery دیگه دارم که فقط به یک جدول وصله . در واقع عملیات افزودن رو با AdoQuery اولیه انجام میدم و دومی که گفتم برای نمایش اطلاعاته . (البته که خوب بنا به دلایل خاصی این کار رو انجام میدم)
و حال برای اینکه بعد از هر ثبت اطلاعات توی AdoQuery اول ، توی AdoQuery دوم نشانداده بشه باید REfresh بشه .
که خوب Open , Close خیلی وقت میگیره (تعداد فیلدهای جدولم 70 تا هست) و Requery خیلی سریع .
من اون مطالبی رو که شما گفتید رو قوبول دارم اخه وقتی خودم هم دقیق معنی کردم به همین نتیجه رسیدم . پس دلیل این تفاوت سرعت در چیه ؟
دیده ها رو باید باور کرد یا شنیده ها رو ؟:گیج:

rabbanieng
یک شنبه 13 بهمن 1387, 00:52 صبح
یک تفاوتی که ریکوئری با باز و بسته کردن کوئری دارد این است که در اولی در صورت آپدیت رکورد فعال تغییر نمی کند ولی در دومی اولین رکورد، رکورد فعال می شود.

vcldeveloper
یک شنبه 13 بهمن 1387, 05:05 صبح
یک تفاوتی که ریکوئری با باز و بسته کردن کوئری دارد این است که در اولی در صورت آپدیت رکورد فعال تغییر نمی کند ولی در دومی اولین رکورد، رکورد فعال می شود.
این سورس Requery در دلفی هست:


procedure TCustomADODataSet.Requery(Options: TExecuteOptions = []);
begin
CheckBrowseMode;
InternalRequery(Options);
First;
end;


می بینید که بعد از Requery، رکورد جاری را با استفاده از First به رکورد اول تغییر میده.

این هم سورس InternalRequery هست که در کد بالا استفاده شده:


procedure TCustomADODataSet.InternalRequery(Options: TExecuteOptions = []);
begin
if FConnectionChanged then
DatabaseError(SCantRequery);
try
Recordset.Requery(ExecuteOptionsToOrd(Options));
except
if Recordset.State = adStateClosed then Close;
raise;
end;
DestroyLookupCursor;
end;

همونطور که مشخص هست، به جز یکسری چک کردن وقوع خطا، تنها کار مهمی که انجام میده، فراخوانی متد Requery از Recordset هست. Recordset همون شی Recordset در ADO مایکروسافت هست. یعنی از اینجا به بعد، روند اجرای کد از سورس دلفی خارج میشه، و میره توی یکی از DLL های مربوط به ADO مایکروسافت. توضیحات مربوط به رفتار Requery در داخل ADO را هم چند پست بالاتر از راهنمای ADO کپی کردم و گذاشتم.

panjere
پنج شنبه 28 خرداد 1388, 18:19 عصر
با سلام؛

Requery خودش چند تا Option داره، مي‌شه بگيد هر كدوم چه كاري انجام مي‌ده و به چه دردي مي‌خوره؟