PDA

View Full Version : بهینه نمودن کوئری



rezayeman
شنبه 13 تیر 1394, 08:47 صبح
با سلام
من یک کوئری به صورت زیر نوشتم اما چون اطلاعات داخل جدول BarcodeInPalet خیلی زیاده این کوئری حدود 10 دقیقه طول میکشه تا اجرا بشه

کسی راه حلی بهتری داره؟

select * from Palet p inner join UserName u
on u.username = p.UserName
where PaletNum in (select PaletNum from BarCodeInPalet where BarCode like '%1432698%')

SabaSabouhi
شنبه 13 تیر 1394, 09:30 صبح
با سلام
من یک کوئری به صورت زیر نوشتم اما چون اطلاعات داخل جدول BarcodeInPalet خیلی زیاده این کوئری حدود 10 دقیقه طول میکشه تا اجرا بشه

کسی راه حلی بهتری داره؟

select * from Palet p inner join UserName u
on u.username = p.UserName
where PaletNum in (select PaletNum from BarCodeInPalet where BarCode like '%1432698%')

سلام
خوب چرا join نمی‌کنی؟ select تو select معلومه که کنده.


SELECT * FROM Palet p
JOIN BarCodeInPalet b on b.PaletNum = p.PaletNum AND BarCode like '%1432698%' )
JOIN UserName u on u.username = p.Username

این رو امتحان کن، این شکلی سرعت باید خیلی بالاتر بره.
در ضمن، روی BaCode یک اندیس بگذار، این هم به سرعت کمک می‌کنه.

صبا صبوحی

tooraj_azizi_1035
شنبه 13 تیر 1394, 10:47 صبح
سلام
شرط LIKE چون در اول اون % اومده اجازه استفاده از ایندکس رو نمیده. نمی تونید قسمت Like رو تغییر بدید؟

rezayeman
شنبه 13 تیر 1394, 11:44 صبح
سلام
خوب چرا join نمی‌کنی؟ select تو select معلومه که کنده.


SELECT * FROM Palet p
JOIN BarCodeInPalet b on b.PaletNum = p.PaletNum AND BarCode like '%1432698%' )
JOIN UserName u on u.username = p.Username

این رو امتحان کن، این شکلی سرعت باید خیلی بالاتر بره.
در ضمن، روی BaCode یک اندیس بگذار، این هم به سرعت کمک می‌کنه.

صبا صبوحی


سلام

نه دوست عزیز نمیشه. سرعتش همونه

rezayeman
شنبه 13 تیر 1394, 11:44 صبح
سلام
شرط LIKE چون در اول اون % اومده اجازه استفاده از ایندکس رو نمیده. نمی تونید قسمت Like رو تغییر بدید؟


سلام

نمیشه حذف کرد. چون اینطوری کاربر مجبوره کل بارکد وارد کنه

البته اینم بگم بکه با =هم امتحان کردم تغییری نداره

N_D
شنبه 13 تیر 1394, 12:19 عصر
به cashplan نگاه کن و یکی از سه حالت زیر رو امتحان کن شاید به کارت اومد.

<CODE>
select * from Palet p inner loop join UserName u
on u.username = p.UserName
where PaletNum in (select PaletNum from BarCodeInPalet where BarCode like '%1432698%')
--------------------------------------------------
select * from Palet p inner merge join UserName u
on u.username = p.UserName
where PaletNum in (select PaletNum from BarCodeInPalet where BarCode like '%1432698%')
----------------------------------------------------
select * from Palet p inner hash join UserName u
on u.username = p.UserName
where PaletNum in (select PaletNum from BarCodeInPalet where BarCode like '%1432698%')
--------------------------------------------
<CODE/>

rezayeman
شنبه 13 تیر 1394, 12:30 عصر
به cashplan نگاه کن و یکی از سه حالت زیر رو امتحان کن شاید به کارت اومد.

<CODE>
select * from Palet p inner loop join UserName u
on u.username = p.UserName
where PaletNum in (select PaletNum from BarCodeInPalet where BarCode like '%1432698%')
--------------------------------------------------
select * from Palet p inner merge join UserName u
on u.username = p.UserName
where PaletNum in (select PaletNum from BarCodeInPalet where BarCode like '%1432698%')
----------------------------------------------------
select * from Palet p inner hash join UserName u
on u.username = p.UserName
where PaletNum in (select PaletNum from BarCodeInPalet where BarCode like '%1432698%')
--------------------------------------------
<CODE/>


میشه توضیح بدی کارشون چیه؟

هر سه تاش واقعا عالی بودن
تو کمتر از 1 ثانیه جواب میده

SabaSabouhi
شنبه 13 تیر 1394, 12:58 عصر
سلام

نمیشه حذف کرد. چون اینطوری کاربر مجبوره کل بارکد وارد کنه

البته اینم بگم بکه با =هم امتحان کردم تغییری نداره

سلام
مطمئنی مشکل از query هست؟ ممکنه از برنامه‌ات باشه. این Query رو توی Management Studio اجرا کن و زمان رو اونجا
اندازه بگیر.
زمان 10 دقیقه زمان خیلی زیادیه.

صبا صبوحی

rezayeman
شنبه 13 تیر 1394, 13:04 عصر
این برنامه راه اندازی شده و دیتابیسش توی سروره و هیچ مشکلی نداره

مقادیر جدول
BarCodeInPalet بالای 1000000 هستش واسه همین کند شده

قبلا که اطلاعاتش کم بود خیلی سریع جواب میداد

xsbehx
شنبه 13 تیر 1394, 15:17 عصر
شما بگو یک میلیارد رکورد ! 10 دقیقه غیر عادیه
برای اینکه بفهمی مدت زمان اجرای برنامت دقیقا چقدره و از چه منابعی استفاده می کنه و چه اتفاقاتی می افته اینکارها رو که می گم بکن:
اول این دو خط کد رو می زنی تا بتونی زمان اجرای کوئری ها رو بدست بیاری


set statistics io on
set statistics Time on

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


checkpoint
dbcc DROPCLEANBUFFERS
checkpoint


حالا کوئری مورد نظرتو رو انتخاب کن و های لایت کن بعد اجراش کن. تو قسمت پایین که خروجی رو نشون می ده یک تب اضافه شده که نوشته Message
اونجا می تونی اطلاعات زمان اجرای کوئری تو CPU و RAM و ... رو ببینی
حالا اگر بخوای ببینی که موقع کوئری زدن چه اتفاقاتی برای کوئری می افته اول باید پلن های در حال اجرا رو پاک کنی با این دستور


dbcc freeproccashe

حالا دوباره کوئری رو انتخاب کن و کلیدهای Ctrl+L رو بزن تا Execute plan رو بهت نشون بده تا بفهمی چه بلایی سر کوئری هات می یاد.
حالا بیا بر همین اساس کدها رو تغییر بده و زمانش رو مشاهده کن.
یکی از راهکارهای ساده اما موثر اینه که :
هیچ موقع از * تو select استفاده نکن و همیشه تمام فیلدهات رو ذکر کن
به جای استفاده از اسم جداولت از [dbo].[EsmeTabel] استفاده کن
و ...

بعد از اینکه این دوتا کار ساده و احیانا کارهای دیگه رو که کردی جوابشو بده ببینیم زمانش چقدر تغییر کرده


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

راستی قبل از هر کاری backup یادت نره!
البته دستورات مورد نظر اصلا کاری با data نداره و فقط کش ها که برای افزایش کارایی به کار می رن رو رفرش می کنه
اگر بازهم مشکلی داری می تونی اصلا پلن کش ها رو پاک نکنی و فقط با دوتا دستور اول و بعدش اجرا دستور مورد نظر زمان اجرا رو بدست بیاری ولی چون دستورات قبلا اجرا شده و کش شده مطمئنا سرعتش بالاتره و زمانش شاید دقیق نباشه

اخر کار هم همه اونهایی که ON کرده بودی رو OFF کن


set statistics io off
set statistics Time off

Kaziveh
شنبه 20 تیر 1394, 03:27 صبح
لطفا اگر براتون مقدور هست بفرمایید این دستورات چکار میکنند و چه فرقی با join های ساده دارند .ممنون

Kaziveh
یک شنبه 21 تیر 1394, 23:35 عصر
لطفا اگه کسی میدونه یه توضحیح در مورد این join هایی که در بالا نوشته شده اند بگه . منظورم merge و loop و ... هستش .ممنون

Ebrahim11
دوشنبه 22 تیر 1394, 10:21 صبح
لطفا اگه کسی میدونه یه توضحیح در مورد این join هایی که در بالا نوشته شده اند بگه . منظورم merge و loop و ... هستش .ممنون

سلام

آموزش کامل رو در این سایت بخوانید .

http://www.madeiradata.com/loop-hash-and-merge-join-types/

niloofar_f
سه شنبه 14 مهر 1394, 19:00 عصر
به cashplan نگاه کن و یکی از سه حالت زیر رو امتحان کن شاید به کارت اومد.

<CODE>
select * from Palet p inner loop join UserName u
on u.username = p.UserName
where PaletNum in (select PaletNum from BarCodeInPalet where BarCode like '%1432698%')
--------------------------------------------------
--------------------------------------------
<CODE/>

سلام
میشه لطفا نحوه استفاده از این دستورها رو بگید. من به این شکل استفاده میکنم error میده!

مهدی نان شکری
سه شنبه 14 مهر 1394, 21:14 عصر
با سلام
هر RDBMS فرآیندی برای اجرای یک کوئری دارد که یکی از معروفترین این مراحل، مرحله انتخاب روش اجرای کوئری می باشد. پایگاه داده ها معمولا از روش های متفاوتی برای انتخاب روش اجرای یک کوئری استفاده می کنند که در این میان MSSQL از روش cost base برای انتخاب روش اجرا بهره می برد به این معنی که روشی توسط RDBMS مورد استفاده قرار بگیرد که کمترین هزینه اجرا را داشته باشد.

معمولا برای اجرای Join ، مایکروسافت SQL از چهاراستراتژی متفاوت بهره می گیرد که عبارتند از Merge Join، Hash Join ، Remote Joinو Loop Join.

بهینه ساز MSSQL با معیارهایی یکی از این چهر استراتژی را انتخاب میکند.
به طور مثال زمانی که یک جدول از جداول Join دارای تعداد رکورد کمتری باشد استراتژی Loop مورد استفاده قرار می گیرد.
روش اجرا به این صورت است که RDBMS مانند حلقه for تک تک رکورد های جدولی که دارای تعداد رکورد بیشتر است پیمایش شده و به ازای هر رکورد به دنبال رکورد متناظر در جدول کوچکتر می گردد.

روش Merge هم زمانی اتفاق می افتد که هر دو جدول بر روی کلید های Join مرتب شده باشند.

همان طور که می بینید هر کدام از استراتژی ها، در شرایط خاص توسط بهینه ساز انتخاب می گردد.
حال می توان توسط Hint هایی بهینه ساز را مجبور به انتخاب روش مورد نظر خود کرد!
دقت کنید ممکن است در شرایط کنونی این روش به ظاهر خوب باشد ولی چون مدام داده ها در جداول تغییر میکنند بهتر است از روش Force کردن بهینه ساز استفاده نکنید تا Optimizer خود بهینه ترین الگوریتم را انتخاب و اجرا نماید.

niloofar_f
سه شنبه 14 مهر 1394, 21:57 عصر
خیلی ممنون از پاسخ کاملتون، ولی یک سوال:

آیا این موارد درمورد اکسس هم صدق میکنه؟

و چطور میتونیم در اکسس زمانی که به سرور لینک هست سرعت اجرا رو بالا ببریم؟