ورود

View Full Version : مقایسه پردازش با SQL و دات نت



tabatabaeefar
پنج شنبه 21 مهر 1390, 00:37 صبح
من دارم یه برنامه مینویسم که قراره کار پردازش اطلاعات مربوط به یک آزمون 4 گزینه ایی رو انجام بده.
خود برنامه با دات نت نوشته میشه و پایگاه داده اون قراره SQL باشه.
من اول میخواستم کار پردازش رو توی دات نت و با استفاده از امکانات اون انجام بدم.
بعد به نظرم رسید با توجه به اینکه امکان داره تعداد رکوردهای جداول حدود سه میلیون بشه اگر این کار رو با خود SQL انجام بدم خیلی بهتره.
3 روزه دارم همش SQL میخونم.
تقریبا هیچی بلدنبودم اما الآن یه چیزایی یاد گرفتم.
میخواستم بدونم به نظر شما کدوم منطقی تره؟ پردازش با دات نت یا SQL
این رو هم در نظر بگیرید که من 3 ساله دات نت کار میکنم و 3 روزه اومدم سراغ SQL
همچنین دقت برنامه هم برام خیلی مهمه.
لطفا مزیت ها و معایب هر دو رو بگید و در آخر نظر خودتون رو هم بفرمایید.
ممنون

حمیدرضاصادقیان
پنج شنبه 21 مهر 1390, 06:40 صبح
سلام.
ببینید بستگی به نوع برنامه داره. یک وقت هست شما میتونید همه رکوردها رو یک بار در Cache فراخوانی کنید و روی اون کار کنید ، یک بار دیگه اینکه دائم با اطلاعات روی جداول شما کار دارید .
معمولا در برنامه هایی که تعداد رکوردها زیاده ، و مجبوره در یک سیستم شبکه دائم از سرور اطلاعات بخونه و روی اون تحلیل انجام بده بهتره تمام پردازش ها سمت سرور صورت بگیره و نتیجه به کلاینت ارسال بشه.که در این حالت ترافیک شبکه پایین میاد و سرعت برنامه افزایش پیدا خواهد کرد.
ولی در برنامه ای که به صورت تکی کار میکنه و پردازش یک بار روی همه داده ها صورت میگیره میتونه داده ها رو به سمت کلاینت فراخوانی کنه و روی اون پردازش انجام بده.
البته باز درحالت دوم اگر جداولتون از ایندکسهای مناسب استفاده کرده باشه و ساختار جداول مناسب باشه استفاده از SP در سمت سرور برای پردازش روی اطلاعات باعث افزایش سرعت شما خواهد شد.

tabatabaeefar
پنج شنبه 21 مهر 1390, 21:27 عصر
ممنون آقای صادقیان
من برنامه رو توی دات نت نوشتم
با استفاده از select رکوردهای مربوطه رو انتخاب کردم، توی یه DataTable پردازش رو انجام دادم و داده های جدید رو با استفاده از دستور Update ذخیره کردم.
این پردازش برای صدهزار رکورد انجام شد.
زمان انتخاب و پردازش روی هم 10 ثانیه طول کشید که خیلی عالی بود.
اما زمان ذخیره سازی با دستور Update حدود 15 دقیقه به طول انجامید که به نظرم این یک فاجعست.
با این وجود اگر بخوام 3 میلیون رکورد رو ذخیره کنم باید حدود 7 ساعت و نیم معطل بشم.
لطفا راهنماییم کنید.
1- اگر با خود SQL هم کد بنویسم همین قدر طول میکشه؟
2- بهتره از چه روشی استفاده کنم.
ممنون

ASKaffash
شنبه 23 مهر 1390, 07:58 صبح
سلام
چند سئوال :
آیا بخش محاسبه که در دات نت در حال انجام است خیلی پیچیده و محاسباتی است ؟
آیا حتما باید نتیجه محاسبات در مثلا یک فیلد در جدول ذخیره شود؟ (الزام است یا اختیار)
آیا دستوراتی که در دات نت پیاده سازی شده حتما معادل T-SQL دارد؟

tabatabaeefar
شنبه 23 مهر 1390, 08:35 صبح
سلام
کدهایی که توی دات نت نوشتم خیلی پیچیده نیستن.
بله حتما باید نتیجه محاسبات در چندین فیلد از چندین جدول نوشته بشه.
فکر میکنم بشه دستورات رو با خود SQL نوشت. اما چون قبلا دستورات رو با دات نت نوشتم و آشنایی کمی با SQL دارم نخواستم ریسک کنم.
راستش رو بخواهید از خطا های احتمالی که میتونه موقع اجرای برنامه اتفاق بیفته یه خورده میترسم.
اما اگر بدونم اگر با خود SQL کد بنویسم مشکلم حل میشه ، حتما این کار رو انجام میدم.
الآن یک هفته است که همش دارم SQL میخونم.(خیلی جالبه. داره خوشم میاد.)/
جزوه شما رو هم خیلی خوندم. دستتون دردنکنه. خیلی خیلی عالی بود.

حمیدرضاصادقیان
شنبه 23 مهر 1390, 10:24 صبح
به قول آقای کفاش شما چرا این پردازش رو داخل خود SQL Server انجام نمیدید؟ چه لزومی داره که دیتا رو یک بار فراخوانی کنید روش تغییرات بدید و بعد به کاربر نمایش بدید.

tabatabaeefar
شنبه 23 مهر 1390, 11:05 صبح
یعنی اونجوری مشکلم حل میشه؟

حمیدرضاصادقیان
شنبه 23 مهر 1390, 14:38 عصر
بستگی به کارتون داره. ولی بیشتر مواردی که نیاز به پردازش اطلاعات هست رو میشه سمت سرور با دستورات خود T-SQL انجام داد.

ASKaffash
یک شنبه 24 مهر 1390, 07:25 صبح
سلام
اگر محاسبات خیلی سنگین نیست و ارتباطات داده ای بین رکوردها کم است پیشنهاد میکنم یک Trigger روی جدول مورد نظر پیاده سازی کنید ( ازنوع After) و در آن Trigger محاسبات را انجام و درون فیلد مورنظرتان UpDate کنید اگر نوع کار را هم ذکر کنید با جزئیات بیشتری میتوان راهنمائی کرد

حمیدرضاصادقیان
یک شنبه 24 مهر 1390, 09:13 صبح
البته اگر بتونید عملیات رو از Trigger به داخل SP هدایت کنید روی بازدهی اطلاعات و سرعت کارتون تاثیر به سزایی خواهد داشت.

tabatabaeefar
یک شنبه 24 مهر 1390, 10:04 صبح
ببخشید اینقدر من مزاحمتون میشم.
من یه SP نوشتم که توش از 2 تا تابع ( که اونا رو هم خودم نوشته بودم ) استفاده کردم.
قبل از پردازش ( یا میشه گفت به عنوان مرحله اول ) باید چندتا رشته که توی یک رشته نوشته شده و با * از هم جدا شده اند را به رشه های مجزا تفکیک کنم.
میدونم که تعداد این رشته ها که توی یک رشته قرار گرفته اند از 18 تا بیشتر نمیشه. مثلا abc*d*efgh*i
باید در مرحله اول این یک فیلد رو به چند تا فیلد تقسیم کنم و توی یک جدول دیگه بنویسم. توی دات نت میشه راحت از Split استفاده کرد.
من از روش زیر استفاده کردم.
خیلی زمان بر بود. از قبل بیشتر شد!!
اگر امکان داره لطفا راهنمایی کنید.


create function CharFind(@MainString varchar(300), @CharF char, @Index smallint)
returns smallint
as

begin

Declare @LocalityValue smallint, @LenN smallint, @Pointer smallint, @Repeat smallint
set @LenN = len(@MainString)
set @Pointer = 1
set @LocalityValue = 0
set @Repeat = 0

while @Pointer <= @LenN
begin

if SUBSTRING(@MainString, @Pointer, 1) = @CharF
begin

if @Repeat = @Index - 1
set @LocalityValue = @Pointer

set @Repeat = @Repeat + 1

end

set @Pointer = @Pointer + 1

end

return @LocalityValue

end


alter function GetString(@MainString varchar(300), @Index smallint)
returns varchar(300)
as

begin

Declare @KeyValue varchar(300), @StartL smallint, @LenL smallint

set @MainString = '*' + @MainString + '*'
Set @StartL = dbo.CharFind(@MainString, '*', @Index) + 1
set @LenL = dbo.CharFind(@MainString, '*', @Index + 1) - @StartL

if dbo.CharFind(@MainString, '*', @Index + 1) = 0
return ''

set @KeyValue = SUBSTRING(@MainString, @StartL, @LenL)

return @KeyValue

end


create proc SP_Process_0
as
begin

insert into Receive2 select dbo.GetString(TextReceive,1), dbo.GetString(TextReceive,2),
dbo.GetString(TextReceive,3), dbo.GetString(TextReceive,4),
dbo.GetString(TextReceive,5), dbo.GetString(TextReceive,6),
dbo.GetString(TextReceive,7), dbo.GetString(TextReceive,8),
dbo.GetString(TextReceive,9), dbo.GetString(TextReceive,10),
dbo.GetString(TextReceive,11), dbo.GetString(TextReceive,12),
dbo.GetString(TextReceive,13), dbo.GetString(TextReceive,14),
dbo.GetString(TextReceive,15), dbo.GetString(TextReceive,16),
dbo.GetString(TextReceive,17), dbo.GetString(TextReceive,18)

from Receive1

end

ASKaffash
سه شنبه 26 مهر 1390, 11:48 صبح
سلام
چند نکته :
تابع CharFind وظیفه پیدا کردن وقوع n ام * را در رشته بعهده دارد تا اینجا مشکلی نیست ولی روی یک رشته خاص در تابع GetString شما عملا 18 بار پیمایش میکند از طرفی درون دات نت شما با متد Split یک مجموع رشته را ایجاد و بعد تحویل SQL میدهید
شماg نباید از تابع استفاده کنید چه جوری :
چون در SQLServer به شکل کامل زبانهای برنامه نویسی آرایه نداریم بنابراین الگوریتم شما یک رشته را پیمایش میکند و در یک رشته هنگامیکه کارکتر * یافت دستور Select را بصورت Dynamic ایجاد میکند ولی چون شما 18 فیلد دارید حلقه ای که پیمایش را انجام میدهد باید برای باقیمانده پیدا شده از 18 عدد مقدار خالی را به رشته Dynamic شما اضافه کند بعد با دستور Exec این رشته Dynamic را اجراکنید
بعدا به تریگر عوض شود