ورود

View Full Version : آیا 0.003 ثانیه برای اجرای.... زیاده؟



resident
دوشنبه 14 مرداد 1392, 22:20 عصر
سلام.
من برای Insert جداول یک Dynamic Query نوشتم . زمان اجرای این کوئری یه بار 0.003 ثانیه است. یه بار 0.017 ثانیه ، یه بار 0.030 و گاهی 0.00 است. اگر دستور Insert رو به صورت معمولی برای هر جدول بنویسم زمان اجرا 0 خواهد بود.
حالا میخوام بدونم زمان اجرای Dynamic Queryبعدا مشکلی برام ایجاد نمی کنه؟ تعداد دفعات اجرای این کوئری نهایت نهایت 50 بار در دقیقه خواهد بود(که احتمالش ضعیفه- معمولا حدود 20-30 بار خواهد بود)

Dynamic Query رو حذف کنم و Insert ها رو عادی بنویسم یا اینکه برام مشکلی ایجاد نمی کنه؟

یوسف زالی
سه شنبه 15 مرداد 1392, 00:04 صبح
سلام.
داینامیک کوئری در حالت های غیرعادی کاربرد داره و در هر بار اجرا یک سری سربار تولید می کنه.
در ضمن نمی شه تکنیک های سریع تر کردن مثل ایندکس و این چیزها رو، اگر نشه گفت نه، بصورت خوب پیاده کرد.
برای مواقعی که راه چاره وجود داره هیچ وقت داینامیک نزنید.

resident
سه شنبه 15 مرداد 1392, 09:08 صبح
داینامیک کوئری در حالت های غیرعادی کاربرد داره و در هر بار اجرا یک سری سربار تولید می کنه.
سربار I/O ایجاد می کنه؟


در ضمن نمی شه تکنیک های سریع تر کردن مثل ایندکس و این چیزها رو، اگر نشه گفت نه، بصورت خوب پیاده کرد.
حتی روی insert,update,delete? تکنیک های سریعتر کردن مگه فقط برای select ها نیست؟

یوسف زالی
سه شنبه 15 مرداد 1392, 09:20 صبح
نه بابا. ران کردن یا نکردن یک ایندکس می تونه هنگام اینسرت هم تفاوت محسوسی ایجاد کنه.
سربارش رو دقیق باید بررسی کنم ولی همین طوری سرسری می دونم که مثلا باید برای هر بار اجرا از اول تمام پلان های اس کیو ال براش ران شه و بهینه سازی هم انجام شه که زمان بره.
دقیق ترش رو می تونی از دوست خوبم آقای سلیم بپرسی.

resident
سه شنبه 15 مرداد 1392, 09:53 صبح
یکی از معایبی که در مورد داینامیک کوئری ذکر میشه اینه که SQL برای اون نمیتونه بهترین Plan اجرا رو کش کنه.
این قضیه در مورد Select درسته ولی آیا در مورد Insert , update ,delete هم این قضیه صادقه؟ به نظر میاد بی معنی باشه.

یوسف زالی
سه شنبه 15 مرداد 1392, 10:04 صبح
ممکنه در شرطهای آپدیت دارای سلکت باشید پس همچین بی معنی هم نیست.

محمد سلیم آبادی
سه شنبه 15 مرداد 1392, 17:08 عصر
لطفا کد insert اتان را در اینجا قرار بدین تا بررسی بشه. و توضیحاتی هم راجب کدتان بدهید.
دستور select فقط query محسوب نمیشه که. Insert، update و delete هم query هستند. مثلا شما میخواهید نتیجه join چند جدول را در یک جدول درج کنید یا اینکه میخواهید یک مجموعه ای مشخص را از یک جدول بدست آورده و آن ها را حذف کنید همه این ها query محسوب میشن. و برای هر کدام از این دستورات plan ای ایجاد میشه و در آن مشخص است که از ایندکس استفاده شده است یا نه اگر استفاده شده از چه ایندکسهایی و از این دست صحبت ها.


Dynamic Query رو حذف کنم و Insert ها رو عادی بنویسم یا اینکه برام مشکلی ایجاد نمی کنه؟
اگر امکان انجام این کار بصورت عادی وجود داشت چرا پس dynamic را انتخاب کردین؟

resident
سه شنبه 15 مرداد 1392, 17:39 عصر
جناب سلیم آبادی. بابت وقتی که گذاشتید تشکر می کنم.
به عنوان مثال من یه SP نوشتم با عنوان GeneralDelete که در همه SPهای Delete فقط همین SP صدا زده میشه.



ALTER procedure [system].[GeneralDelete]
@SchemaName nvarchar(50),
@TableName nvarchar(70),
@PrimaryKeyValue nvarchar(100),
@Condition nvarchar(max),
@OldConcurrencyVersion timestamp,
@UserID int,
@ErrorNumber int out,
@RelatedTables nvarchar(max) out
as
begin

SET NOCOUNT ON;

SET @ErrorNumber=0
Begin Try
declare @StoredProcedureName nvarchar(150)
set @StoredProcedureName='['+@SchemaName+']'+'.'+'['+@TableName+'Delete]'

exec [system].CheckConcurrency @SchemaName,@TableName,@PrimaryKeyValue,@StoredPro cedureName,@OldConcurrencyVersion,@UserID ,@ErrorNumber out

if @ErrorNumber=0
begin
exec [system].[CheckTablesRelationships] @SchemaName,@TableName,@StoredProcedureName,@Prima ryKeyValue,@UserID,@ErrorNumber out,@RelatedTables out
End


if @ErrorNumber=0 and @RelatedTables=''
begin
exec [system].[BaseDelete] @SchemaName ,@TableName ,@PrimaryKeyValue,@Condition , @StoredProcedureName ,@UserID ,@ErrorNumber out
end
End Try
Begin Catch

exec [system].[ErrorLogInsert] @StoredProcedureName,'[system].[GeneralDelete]',@UserID,@ErrorNumber out

End Catch

END




داخل این SP، Concurrency ها و ارتباط با سایر جداول چک میشه و در صورتیکه وابستگی وجود نداشته باشه عملیات حذف انجام میشه. برای اینکه در همهSP های حذف دستورات تکراری نوشته نشه SP مربوط به حذف هم به صورت دینامیک نوشته شده.

محمد سلیم آبادی
چهارشنبه 16 مرداد 1392, 03:47 صبح
آیا در روش عادی که در پست اول راجبش صحبت کردین همین بررسی هایی که در حالت داینامیک وجود داره را نیز انجام میدین؟ یا فقط یک درج یا حذف ساده؟

resident
چهارشنبه 16 مرداد 1392, 09:26 صبح
در SP که گذاشتم داخل [system].[BaseDelete] دستور Delete رو به صورت دینامیک نوشتم که دیگه برای هر جدول نیام دستور Delete بنویسم.
اینم SP اش:




ALTER procedure [system].[BaseInsert]
@TableFullName nvarchar(100),
@Columns nvarchar(max),
@ValueColumns nvarchar(max),
@UserID int,
@ErrorNumber int out

as
begin

SET NOCOUNT ON;
set @ErrorNumber=0
declare @SQLQuery nvarchar(max)

Begin Try

Set @SQLQuery = 'insert into '+@TableFullName +'('+@Columns+') values('+ @ValueColumns +')'
Execute sp_Executesql @SQLQuery

End Try
Begin Catch

declare @StoredProcedureName nvarchar(100)=@TableFullName+'Insert'
exec [system].[ErrorLogInsert] @StoredProcedureName,'[system].[BaseInsert]',@UserID,@ErrorNumber out

End Catch
END








آیا در روش عادی که در پست اول راجبش صحبت کردین همین بررسی هایی که در حالت داینامیک وجود داره را نیز انجام میدین؟ یا فقط یک درج یا حذف ساده؟
در مورد حذف و آپدیت بله ولی در مورد Insert خیر.
در مورد Insert فقط ورود اطلاعاته.چک کردنی وجود نداره.

محمد سلیم آبادی
چهارشنبه 16 مرداد 1392, 11:29 صبح
در SP که گذاشتم داخل [system].[BaseDelete] دستور Delete رو به صورت دینامیک نوشتم که دیگه برای هر جدول نیام دستور Delete بنویسم.
اینم SP اش:
در مورد delete صحبت میکنید بعد کد پروسیجر insert را پست میکنید :)


در مورد Insert فقط ورود اطلاعاته.چک کردنی وجود نداره.
خب این کد پروسیجری که گذاشتین مدل داینامیک بود دیگه؟ خب مدل سادش و عادیش چیه؟

زمان هایی که در پست اول قرار دادین که زمان خاصی نیستند. 1 هزارم ثانیه زمانی نیست. پروسیجرهاتون هم که صحیح و سالم به نظر میرسن پس با خیال راحت به کارتون ادامه بدین... :)

resident
چهارشنبه 16 مرداد 1392, 13:38 عصر
خب این کد پروسیجری که گذاشتین مدل داینامیک بود دیگه؟ خب مدل سادش و عادیش چیه؟


اگه دینامیک ننویسیم در SP عملیات حذف هر جدول باید یکبار دستور Delete رو بنویسم. به عنوان مثال برای جدول City:
به جای [system].[BaseDelete] در SP ی [GeneralDelete] مینویسیم:

Delete From City
Where CityID=@CityID


مسئله ای که هست اینه که دوستمون می گفتند به خاطر مسائلی که دینامیک کوئری ها دارن ، تا مجبور نشدید از دینامیک کوئری ها استفاده نکنید جون SQL نمیتونه پلنشونو کش کنه و ....


زمان هایی که در پست اول قرار دادین که زمان خاصی نیستند. 1 هزارم ثانیه زمانی نیست.
این زمان گاهی تا 0.03 ثانیه هم میرسه.مشکلی نداره؟

یوسف زالی
چهارشنبه 16 مرداد 1392, 19:32 عصر
معمولا زمانهایی که زیر یک ثانیه گرفته می شه رو باید با حلقه های تکرار مثلا هزار بار بگیرید تا زمان درست در بیاد.
داینامیک کوئری معضل نیست. اما اگر راه ساده داره خب دلیلی نداره از این روش استفاده بشه. اگر با استفاده از داینامیک زمان مناسبی دریافت می کنید ایرادی نداره و ازش استفاده کنید.