PDA

View Full Version : سوال: کمک برای بهینه کردن SP



علیرضا حسن زاده
شنبه 08 خرداد 1389, 16:49 عصر
سلام من از SP زیر برای گرفتن اطلاعات یکی از جدول های دیتابیسم استفاده می کنم:

CREATE PROCEDURE spCarDefGetData
@Year as int
AS
BEGIN
SET NOCOUNT ON;
Declare @count as int
Set @count = (Select Count(id) From CarDef Where [Year]>=@Year)
Select @count,* From CarDef Where [Year]>=@Year
ENDهمون طور که می بینید برای بدست آوردن تعداد سطرهایی که باید برگدونده بشن از یه Select جدا استفاده می کنم علت اینکار هم اینه که می خوام تو C#‎ اطلاعات رو با DataReader بخونم و تو یه لیست قرار بدم (بیشتر هدفم دریافت اطلاعات به صورت ناهمزمان هست تا کاربر برنامه رو هنگ کرده تصور نکنه) تو C#‎ هم از کد زیر برای دریافت اطلاعات استفاده می کنم:

private long Datacount;
public int LoadPercent {get;set;}
public List<CardefInfo> GetData(int currentYear)
{
long count = 0;
if (comm == null)
comm = new SqlCommand();
comm.CommandType = CommandType.StoredProcedure;
comm.CommandText = "dbo.spCarDefGetData";
comm.Connection = GetConnection();
reader = comm.ExecuteReader(CommandBehavior.CloseConnection );
comm.Parameters.AddWithValue("@CurrentYear", currentYear);
KeepOn = true;
if (reader == null) return null;
var retinfo = new List<CardefInfo>();
reader.Read();
long Datacount = Convert.ToInt64(reader[0]);
do
{
retinfo.Add(new CardefInfo
{
Id = Convert.ToInt64(reader["Id"].ToString()),
CarType = reader["Car_type"].ToString(),
Radif = reader["Radif"].ToString(),
Name = reader["Name"].ToString(),
Keshvar = Convert.ToBoolean(reader["Keshvar"]),
Price = Convert.ToInt64(reader["Price"]),
Year = Convert.ToInt16(reader["Year"])
});
count++;
LoadPercent = (long) (((double) count/Datacount)*100);
} while (reader.Read() && KeepOn);
KeepOn = false;
return retinfo;
}همونطور که می بیند تعداد کل سطرها که تو یه ستون توسط SP برگردونده میشه توسط Reader تو متغییر قرار داده میشه و حلقه شروع به دریافت اطلاعات می کنه و هربار درصد اطلاعات لود شده رو تو متغییر LoadPercent قرار میده این تابع رو تو یه Thread اجرا می کنم و روند پیشرفت کار رو به کاربر نشون میدم کلا مشکلی نداره (از نظر خودم تو C#‎ مشکلی نداره مشکل با SQL) ولی نمیدونم چیکار کنم تا با یه Select اینکار رو انجام بدم (البته میشد count رو تو همون Select دوم قرار داد ولی فکر کردم شاید برای هر سطر داده تو SQL یه بار باید Count اجرا بشه که خوب نیست)
دوستان لطفا نظرات و پیشنهادهای خودتون رو بفرمایید تا بتونم عملیات رو بهینه تر و با سربار کمتری انجام بدم
متشکرم

علیرضا حسن زاده
شنبه 08 خرداد 1389, 21:17 عصر
یعنی بهتر از این روش کاری دیگه ای نمیشه کرد یا من سوالمو جای درستی نپرسیدم؟ (کد #C رو نوشتم تا هدفمو از ایجاد تاپیک بهتر بتونم انتقال بدم)

ASKaffash
یک شنبه 09 خرداد 1389, 08:51 صبح
سلام
به نظر من خروجی را در یک DataTable ارسال کنید و برای جلوگیری از هنگ از thread استفاده کنید اینطوری DT.Rows.Count تعداد سطرهای شماست . دوبار جدول دارد Scan می شود

علیرضا حسن زاده
یک شنبه 09 خرداد 1389, 09:41 صبح
سلام
به نظر من خروجی را در یک DataTable ارسال کنید و برای جلوگیری از هنگ از thread استفاده کنید اینطوری DT.Rows.Count تعداد سطرهای شماست . دوبار جدول دارد Scan می شود

درسته که استفاده از DataTable کار رو راحت میکنه ولی تعداد سطرهای موجود در اون بعد از پر شدن DataTable مشخص میشه، هدف من اینه که قبل از شروع به دریافت اطلاعات تعداد سطرهایی رو که باید بگیرم رو، بدونم
همنطور که تو پست اول هم گفتم برای هنگ نکردن از thread استفاده می کنم:لبخندساده: ولی برای اینکه مثلا با یه ProgressBar بتونم میزان پیشرفت کار رو نشون بدم نیاز به داشتن تعداد کل عملیات قبل از شروع به کار هست تا کاربر هم یه چیزی رو صفحه ببینه و فکر نکنه برنامه هنگ کرده چون با اینکه از Thread استفاده می کنم و برنامه هنگ نمیکنه ولی عملا کاربر هم تا Load شدن کامل اطلاعات باید منتظر باشه و در این صورت استفاده از Thread برای هنگ نکردن برنامه زیاد ثمر بخش نیست و باید یه عملیات دیگه پیشرفت کار رو به کاربر اعلام کنه
مشکل من هم با این دوبار Scan شدنه وگرنه برنامه خوب کار میکنه ولی به نظر میاد که اینجوری درست نباشه چون یه سربار اضافی داره
با تشکر از جوابتون

ASKaffash
یک شنبه 09 خرداد 1389, 13:30 عصر
سلام
از ProgressBar برای حالتی که زمان تخمین مشخص نیست استفاده کنید :


Style = System.Windows.Forms.ProgressBarStyle.Marquee

علیرضا حسن زاده
یک شنبه 09 خرداد 1389, 16:03 عصر
سلام
از ProgressBar برای حالتی که زمان تخمین مشخص نیست استفاده کنید :


Style = System.Windows.Forms.ProgressBarStyle.Marquee

روش خوبیه:تشویق: ولی به صورت درصد نشون دادن هم جای خودش رو داره.
یعنی کلا راهی نداره (البته اجرا شدن Select اول باعث میشه Select دوم سریع تر اجرا بشه ولی در کل روش جالبی نیست فقط مشکل رو حل کرده)