PDA

View Full Version : آپ دیت کردن یتا بیس و سرعت پایین



nkm
یک شنبه 07 مرداد 1386, 20:48 عصر
سلام دوستان
من یه برنامه دارم که میاد داده ها را از یک دیتا بیس که TEXT باشه میخونه و در یه بانک SQL ذخیره میکنه

عمل خواندن اطلاعات که حدود 500 مگ هست خوب و سریع هست و در حدود 30 ثانیه طول میکشه، ولی وقتی خط دستور TableAdapter.UpDate();o را اضافه میکنم که دیتا ست را بروز کنه یا خط اضافه شده را به دیتا بیس اضافه کنه، این عمل به 90 دقیقه افزایش پیدا میکنه

آمدم این UPDATE را برای هر 1000 تا رکورد ایجاد کردم، ولی بازهم خیلی تغییر نکرد

خواستم ذر Thread استفاده کنم
ولی مطمئن نبودم که به کارم بیاد (چون اصلا کار نکردم)

اصول این برنامم به این صورته که رشته را از فایل میخونه و به یک تابع میفرسته
تابع رشته را که یک رکورد است به فیلدهاش تفکیک میکنه و بعد در یک ROW میریزه و بعد UPDATE میکنه
رفت و برگشت این تابع زمان زیاد میبره (به خاطر عمل UPDATE)
به ذهنم رسید در زمانی که تابع داره اون عمل تفکیک و بروز رسانی را انجام میده، تابع به صورت مجزا فراخوانی بشه، سرعت افزایش پیدا میکنه

چیزی که به ذهنم رسید همون طور که قبلا اشاره کردم، استفاده از Thread بود
ولی چیزی که من دیدم نمیشه یه تابع را با یک پارامتر به صورت مجزا فراخانی کرد

چکار کنم که سرعت برنامه افزایش پیدا کنه؟؟؟

nkm
سه شنبه 09 مرداد 1386, 20:00 عصر
کسی واقعا راه حلی به ذهنش نمیاد؟؟؟

ghafoori
چهارشنبه 10 مرداد 1386, 14:25 عصر
دوست عزیز ببین این راه چه طوره شما وقتی از فایل اطلاعات را خواندی مستقیما کد اپدیت sql را تولید کن و با یک sqlcommand ان را اجرا کن چون من فکر می کنم برای تولید این کد sql دیتااداپتر طول می دهد

اَرژنگ
چهارشنبه 10 مرداد 1386, 14:42 عصر
کدی که UPDATE را انجام میده بفرستید

nkm
پنج شنبه 11 مرداد 1386, 15:35 عصر
public static void AddToMasterDB(string inPutString)
{

DataSet1 DS = new DataSet1();
DataRow DR = DS.Tables["Master"].NewRow();
DataSet1TableAdapters.MasterTableAdapter DA = new DataSet1TableAdapters.MasterTableAdapter();

DR[0] = inPutString.Substring(0, 1);
DR[1] = inPutString.Substring(1, 15);
DR[2] = inPutString.Substring(16, 4);
DR[3] = inPutString.Substring(20, 13);
DR[4] = inPutString.Substring(33, 22);
DR[5] = inPutString.Substring(55, 10);
DR[6] = inPutString.Substring(65, 7);
DR[7] = inPutString.Substring(72, 25);
DR[8] = inPutString.Substring(97, 20);
DR[9] = inPutString.Substring(117, 10);
DR[10] = inPutString.Substring(127, 2);
DR[11] = inPutString.Substring(129, 1);
DR[12] = inPutString.Substring(130, 2);
DR[13] = inPutString.Substring(132, 7);
DR[14] = inPutString.Substring(139, 6);
DR[15] = inPutString.Substring(145, 6);
DR[16] = inPutString.Substring(151, 2);
DR[17] = inPutString.Substring(153, 10);
DR[18] = inPutString.Substring(163, 5);
DR[19] = inPutString.Substring(168, 6);
DR[20] = inPutString.Substring(174, 9);
DR[21] = inPutString.Substring(183, 10);
DR[22] = inPutString.Substring(193, 1);
DR[23] = inPutString.Substring(194, 6);
DR[24] = inPutString.Substring(200, 10);
DR[25] = inPutString.Substring(210, 10);
DR[26] = inPutString.Substring(220, 2);
DR[27] = inPutString.Substring(222, 2);
DR[28] = inPutString.Substring(224, 1);
DR[29] = inPutString.Substring(225, 6);
DR[30] = inPutString.Substring(231, 10);
DR[31] = inPutString.Substring(241, 10);
DR[32] = inPutString.Substring(251, 6);
DR[33] = inPutString.Substring(257, 6);
DR[34] = inPutString.Substring(263, 6);
DR[35] = inPutString.Substring(269, 3);
DR[36] = inPutString.Substring(272, 10);
DR[37] = inPutString.Substring(282, 3);
//DR[38] = inPutString.Substring(285, 12);
//DR[39] = inPutString.Substring(297, 5);
DR[40] = inPutString.Substring(302, 2);
DR[41] = inPutString.Substring(304, 2);

DS.Tables["Master"].Rows.Add(DR);
DA.Update(DR);


}


public static void DownloadAndInsertMaster(stream strm)
{

System.IO.StreamReader sr = new System.IO.StreamReader(strm);
string line = sr.ReadLine();
while ((line = sr.ReadLine()) != null)
{
AddToMasterDB(line);

}

strm.Flush();
strm.Close();

}

nkm
پنج شنبه 11 مرداد 1386, 15:40 عصر
ممنون میشم اگه یه راهی برام پیدا کنید!:خجالت:

ghafoori
پنج شنبه 11 مرداد 1386, 15:59 عصر
دوست عزیز معلومه کد شما کنده اخه چرا پس از هر اضافه کردنی متد update را فرا می حوانید این خط را
DA.Update(DR);
بعد از حلقه while قرار بدید

Behrouz_Rad
پنج شنبه 11 مرداد 1386, 18:41 عصر
۲- به جایه استفاده از اییندکس مانند : DR[26] از اسمه فیلد استفاده کنید.
خیر!
اینجوری سرعت حدود 30 درصد کاهش پیدا می کنه!
چون باید در HashTable جستجو بشه و اندیس معادل نام فیلد پیدا بشه.

Behrouz_Rad
جمعه 12 مرداد 1386, 10:08 صبح
این کاری که آخر از همه باید انجام بشه. اول خوانایی کد مهمه، چنکه در این حالتی که هستش بیشتر ضرر داره تا فایده. اگر کسی کدش را از اول خوانا ننویسه، سرعت کد آخرین مسئله‌ایه که باید نگرانش باشه.
در ضمن این زمانبری با اندیس فقط وقتی مشکل میشه که با همین روش بخوان ادامه بدند، که این طرزی که نوشته شده استفاده از روشهایه دیگر را که ممکنه از این روش بهتر باشند را الان داره سلب میکنه.
موضوع تاپیک ارتباطی با بحث خوانایی کدها نداره و این رو برنامه نویس مشخص می کنه.
سوال دوستمون در مورد "سرعت اجرای دستورات" هست که موردی رو که گفتی تاثیر مستقیم بر پایین آوردن سرعت خواهد داشت.

موفق باشید.

اَرژنگ
شنبه 13 مرداد 1386, 05:04 صبح
موضوع تاپیک ارتباطی با بحث خوانایی کدها نداره و این رو برنامه نویس مشخص می کنه.
سوال دوستمون در مورد "سرعت اجرای دستورات" هست که موردی رو که گفتی تاثیر مستقیم بر پایین آوردن سرعت خواهد داشت.

موفق باشید.
با اینکه کاملا در مورد "تاثیر مستقیم بر پایین آوردن سرعت " برایه این حالت بخصوص درست میگید، ولی یکی از اصول بالا بردن سرعت این است که آخرین کاریه که باید انجام بشه و نه اولین.
اگر کدی از اول با خوانایی نوشته نشده باشه کوچکترین مشکلی که باهاش مواجه میشند بالا بردن سرعتش است، و انعطاف ناپزیری کد (به دلیل اینکه کد ناخوانا را نمیشه به راحتی تغییر داد) به بالا بردن سرعت هم کمک نمیکنه.
نداشتن ‌اس‌کیو‌الی که برایه آپ‌دیت استفاده میشه هم به این ماجرا کمکی نمیکنه، قبل از اینکه بخواهیم این کد را سریعتر کنیم باید کلی فاکتور دیگر را هم در نظر بگیریم. برایه مثال قسمت where که برایه Update استفاده میشه، آیا داره از یک فیلده ایندکس شده استفاده میکنه ؟
بدانه داشتن یک تصویر کامل ،بحث کردن در مورد سریعتر کردن این کد بخصوص مانند ساختن یک گاری از فایبر گلاس میماند، بهترین گاری هم که ساخته بشه از اسبش تندتر حرکت نخواهد کرد.

مخلصیم

nkm
یک شنبه 14 مرداد 1386, 17:56 عصر
در مورد دستور آپ دیت همه جوره اش را امتحان کردم
یعنی تکی و هزارتایی و ده هزارتایی

مشکل کندی از آپ دیت هست، چون وقتی اون خط دستور را بر میدارم، راحت همه فایل خوانده شده و برنامه تمام میشود.
از بقیه مطالب چیزی نگرفتم!

اَرژنگ
یک شنبه 14 مرداد 1386, 18:14 عصر
در مورد دستور آپ دیت همه جوره اش را امتحان کردم
یعنی تکی و هزارتایی و ده هزارتایی

مشکل کندی از آپ دیت هست، چون وقتی اون خط دستور را بر میدارم، راحت همه فایل خوانده شده و برنامه تمام میشود.
از بقیه مطالب چیزی نگرفتم!
۱ـ "چون وقتی اون خط دستور را بر میدارم" اون خط دستور یعنی چی؟ کدام خط؟ کدام دستور؟
۲ـاس کییو ال آپ‌دیت را پیست کنید
۳ـفیلدهایی کلیدی این جدول را که قراره آپ دیت بشه بفرستید.
۴ـاگر میتوانید یک پروژه کوچک که فقط همین قسمت را داره ضمیمه کنید که ما تمام معلومات دستمان بشه ، اگر یک فایل که قراره آٓپ دیت بشه و داتابیسی که فقط این جدول را با مقدارات داره بفرستید که خیلی بهتر.
۵ـ"در مورد دستور آپ دیت همه جوره اش را امتحان کردم یعنی تکی و هزارتایی و ده هزارتایی" خوب چه نتیجه‌ای گرفتید؟ تکی و هزارتایی و ده هزارتایی همشان یکمقددار زمان میبرند؟ تکی ، تکی اجرا میکنید ۱۰۰ تا رکورد همان مقدار زمان میبره که ۱۰۰ تا را با هم یکدفعه امتحان کنید؟

nkm
دوشنبه 15 مرداد 1386, 10:58 صبح
وقتی خط دستور آپ دیت را بر میدارم خواندن فایل و ریختن آن در DataRow اصلا زمان بر نیست
یعنی استفاده از ایندکس اصلا سرعت را پایین نیاورده
یعنی با حذف کردن دستور اپ دیت سرعت به شدت افزایش یافت ولی به علت پر شدن دیتا ست و آپ دیت نشدن، بعد از حدود 7000 تا رکورد برنامه خطا بر میگرداند که احتمالا از رم سیستم بود
آمدم و هر 5هزارتا رکورد را یکجا آپ دیت کردم، از نظر زمانی شاید 4-5 درصد کاهش یافت که چیز خاصی نبود در مقایل 1 ساعت
من تمام برنامه را براتون فرستادم، تابع دوم یک stream را گرفته و پس از پردازش توسط تابع اول هر خط فایل را تبدیل به یک ROW میکند و بعد در دیتا بیس اضافه میکند
مشکل زمانی است که داره آپ دیت میشود، دیتا بیس اصلا کلید ندارد، البته به طور جحداگانه کلید هم تعریف کردم که نتیجه را ببینم، ولی خوب اصولش هیچ کلیدی ندارد!

اینم از دستور آپ دیت:


UPDATE dbo.Master
SET Status = @Status, Subs_ID = @Subs_ID, Flag = @Flag, FName = @FName, LName = @LName, PostCode = @PostCode, Tel = @Tel, Add1 = @Add1,
Add2 = @Add2, AddCode = @AddCode, Hoze = @Hoze, Freq = @Freq, Shahradi = @Shahradi, Parvandeh_ID = @Parvandeh_ID, RequestON = @RequestON,
ContractOn = @ContractOn, SubsType = @SubsType, MaxConsump = @MaxConsump, Buiding = @Buiding, Zirbana = @Zirbana, Compress = @Compress,
Zarfiat = @Zarfiat, Tax = @Tax, MeterInstallOn = @MeterInstallOn, MeterManufactor = @MeterManufactor, MeterSerial = @MeterSerial,
InstghahModel = @InstghahModel, MeterDigit = @MeterDigit, FlowCode = @FlowCode, ConsumpStartOn = @ConsumpStartOn,
MeterLastFigure = @MeterLastFigure, MeterNextFigure = @MeterNextFigure, MeterLastReading = @MeterLastReading,
MeterNextReading = @MeterNextReading, ContListOn = @ContListOn, BillSequence = @BillSequence, ConsumpAvrage = @ConsumpAvrage,
ConsumpAvrageCounter = @ConsumpAvrageCounter, Mandeh = @Mandeh, MandehRound = @MandehRound, Sazman = @Sazman,
Faaliat = @Faaliat



و اینم دستور Insert:


INSERT INTO dbo.Master
(Status, Subs_ID, Flag, FName, LName, PostCode, Tel, Add1, Add2, AddCode, Hoze, Freq, Shahradi, Parvandeh_ID, RequestON, ContractOn, SubsType,
MaxConsump, Buiding, Zirbana, Compress, Zarfiat, Tax, MeterInstallOn, MeterManufactor, MeterSerial, InstghahModel, MeterDigit, FlowCode,
ConsumpStartOn, MeterLastFigure, MeterNextFigure, MeterLastReading, MeterNextReading, ContListOn, BillSequence, ConsumpAvrage,
ConsumpAvrageCounter, Mandeh, MandehRound, Sazman, Faaliat)
VALUES (@Status,@Subs_ID,@Flag,@FName,@LName,@PostCode,@T el,@Add1,@Add2,@AddCode,@Hoze,@Freq,@Shahradi,@Par vandeh_ID,@RequestON,@ContractOn,@SubsType,@MaxCon sump,@Buiding,@Zirbana,@Compress,@Zarfiat,@Tax,@Me terInstallOn,@MeterManufactor,@MeterSerial,@Instgh ahModel,@MeterDigit,@FlowCode,@ConsumpStartOn,@Met erLastFigure,@MeterNextFigure,@MeterLastReading,@M eterNextReading,@ContListOn,@BillSequence,@Consump Avrage,@ConsumpAvrageCounter,@Mandeh,@MandehRound, @Sazman,@Faaliat)

nkm
دوشنبه 15 مرداد 1386, 11:04 صبح
من اگه بتونم اون تابع اولی را به صورتی قرار بدم که برنامه نخواد صبر بده که تابع انجام بشه و برگرده تا به سراغ رکورد بعدی بره، سرعت برنامه مطمئنا" خیلی افزایش پیدا میکنه (Thread)

ولی چطوری اش را نمیدونم

هرچی هم گشتم چیزی پیدا نکردم، اونهایی هم که یافتم همه یک تابع را اجرا میکردن، ولی قابلیت ارسال پارامتر (که همون یک خط فایل باشه) را نداشتن یا من نیافتم

اَرژنگ
دوشنبه 15 مرداد 1386, 12:33 عصر
من اگه بتونم اون تابع اولی را به صورتی قرار بدم که برنامه نخواد صبر بده که تابع انجام بشه و برگرده تا به سراغ رکورد بعدی بره، سرعت برنامه مطمئنا" خیلی افزایش پیدا میکنه (Thread)

ولی چطوری اش را نمیدونم

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

nkm
دوشنبه 15 مرداد 1386, 14:46 عصر
الان من مجبور شدم که همین کار را بکنم
البته به نحو دیگری
آمدم یک فیلتر گذاشتم و تعداد رکوردهام را به 10 قسمت شکاندم و هر بار همه را با هم آپ دیت میکنم، اینجوری سرعتم به نصف هم کمتر کاهش پیدا کرده
یعنی همزمان 10 تا عملیات را با هم انجام میدم
من فکر میکنم اون دستور آپ دیت خیلی زمان میبره برای تبدیل اون به دستور SQL و آپ دیت کردنش