View Full Version : تغییر در عبارات where و کاهش زمان از 20 دقیقه به 20 ثانیه
حمیدرضاصادقیان
یک شنبه 01 اردیبهشت 1387, 09:43 صبح
سلام دوستان.در برنامه یک کوئری بزرگ بود که روی یک دیتابیس 20 دقیقه طول می کشید.
با بررسی که انجام دادم مشکل در شرط where بود که من اونو به شکل زیر تغییر دادم و سرعت به زیر 20 ثانیه کاهش یافت.
این جمله اول بود
where (select count(f_kol.kol_n) from f_kol where f_kol.kol_n=f_tafzil.kol_n )>0
and (select count(f_moein.moen_n) from f_moein where
F_moein.moen_n=f_tafzil.moen_n ) >0
وجمله دوم این هست که من نوشتم
where (select top 1 isnull(f_kol.kol_n,0) from f_kol where f_kol.kol_n=f_tafzil.kol_n )>0
and (select top 1 isnull(f_moein.moen_n,0) from f_moein where
f_moein.moen_n=f_tafzil.moen_n ) >0
فقط یک سوال با تغییری که من دادم مشکلی که ایجاد نخواهد شد؟
Hamid.Kad
یک شنبه 01 اردیبهشت 1387, 10:48 صبح
بنظر من که مشکل ایجاد میشه.چون کوئری دوم ربطی به کوئری اول نداره. توی اولی شما تعداد رکوردهایی که در شرط صدق می کنند(توی کوئری داخلی) رو بر می گردونید ولی توی دومی اولین رکوردی که فیلد kol_n اون بزرگتر از صفر باشه و در حقیقت به همین خاطر هم هست که اینقدر سریعتر شده چون توی اولی باید کل جدول اسکن بشه ولی توی دومی به اولین رکورد مطلوب که رسید اسکن متوقف میشه
حمیدرضاصادقیان
یک شنبه 01 اردیبهشت 1387, 11:09 صبح
سلام.ممنون.من بازم کوئری رو چک کردم ولی به نظرم این شرط رو برای این گذاشتن که اگر حساب کل یا معین مربوطه وجود نداره این کارو انجام نده ولی من به جای اینکه اینکارو بکنم تست میکنم اگر اولین رکوردش موجود بود اینکارو بکنم اگر نبود که نکنه.
بازم منتظر نظر اساتید هستم.
باتشکر.
e-shahshahani
یک شنبه 01 اردیبهشت 1387, 11:14 صبح
شما همون کوئری اول را بنویس و روی فیلد هایی که در شرط where قرار دارند ایندکس بزن ببین سرعتش چند برابر میشه. (احتمالا این فیلد ها f_kol.kol_n و f_tafzil.kol_n و F_moein.moen_n و f_tafzil.moen_n)
من مشابه اینکار را کردم و جواب گرفتم.
اگر اینکار را کردی نتیجه اش را به ما هم بگو!
Hamid.Kad
یک شنبه 01 اردیبهشت 1387, 11:21 صبح
راستش من سیستمهای حسابداری رو خیلی توش وارد نیستم ولی فکر کنم به اون فیلدی که دارید توش join میزنید بستگی داره. حرف شما درسته یعنی اگه اینجور باشه که فرمودید دستور دومی هم میتونه کار دستور اولی رو انجام بده
حمیدرضاصادقیان
یک شنبه 01 اردیبهشت 1387, 12:53 عصر
ممنون.ولی باز اگه اساتید نظری بدن ممنون میشم. سعی میکنم کل کوئری رو اینجا قرار بدم که تصمیم گیری بهتر باشه.
حمیدرضاصادقیان
یک شنبه 01 اردیبهشت 1387, 21:31 عصر
اینم کل Script
insert into f_hes
(kol_n, moen_n, tafzil_n, kol_c, moen_c, tafzil_c, typ, Bd0, Bs0, Bd1, Bs1, Bd2, Bs2,Bd_t, Bs_t, Tn, Mn)
select f_tafzil.kol_n,f_tafzil.moen_n,f_tafzil.tafzil_n
,(select f_kol.kol_c from f_kol where f_tafzil.kol_n=f_kol.kol_n) AS kol_c
,(select f_moein.moen_c from f_moein where f_tafzil.moen_n=f_moein.moen_n and f_tafzil.kol_n=f_moein.kol_n) AS moen_c
,f_tafzil.tafzil_c
, case
WHEN (select f_kol.mov from f_kol where f_tafzil.kol_n=f_kol.kol_n) =1 THEN (select f_kol.typ from f_kol where f_tafzil.kol_n=f_kol.kol_n)
ELSE (select f_kol.typ from f_kol where f_tafzil.kol_n=f_kol.kol_n)+5
END As typ
,(select IsNull(sum(price),0) from F_sanad
where (f_sanad.date1<'88/01/01') and (f_tafzil.kol_n=f_sanad.kol_n) and (f_tafzil.moen_n=f_sanad.moen_n) and (f_tafzil.tafzil_n=f_sanad.tafzil_n)
and (f_sanad.BD_bs=1) and (f_sanad.ghatei<>2)) As Bd0
,(select IsNull(sum(price),0) from F_sanad
where (f_sanad.date1<'88/01/01') and (f_tafzil.kol_n=f_sanad.kol_n) and (f_tafzil.moen_n=f_sanad.moen_n) and (f_tafzil.tafzil_n=f_sanad.tafzil_n)
and (f_sanad.BD_bs=0) and (f_sanad.ghatei<>2)) As Bs0
,(select IsNull(sum(price),0) from F_sanad
where (f_sanad.date1 >='83/01/01' and f_sanad.date1<='88/01/01') and (f_tafzil.kol_n=f_sanad.kol_n) and (f_tafzil.moen_n=f_sanad.moen_n) and (f_tafzil.tafzil_n=f_sanad.tafzil_n)
and (f_sanad.BD_bs=1) and (f_sanad.ghatei<>2)) As Bd1
,(select IsNull(sum(price),0) from F_sanad
where (f_sanad.date1 >='83/01/01' and f_sanad.date1<='88/01/01') and (f_tafzil.kol_n=f_sanad.kol_n) and (f_tafzil.moen_n=f_sanad.moen_n) and (f_tafzil.tafzil_n=f_sanad.tafzil_n)
and (f_sanad.BD_bs=0) and (f_sanad.ghatei<>2)) As Bs1
,(select IsNull(sum(price),0) from F_sanad
where (f_sanad.ghatei<>2) and (f_sanad.BD_bs=1) and (f_tafzil.kol_n=f_sanad.kol_n) and (f_tafzil.moen_n=f_sanad.moen_n) and (f_tafzil.tafzil_n=f_sanad.tafzil_n) ) As Bd2
,(select IsNull(sum(price),0) from F_sanad
where (f_sanad.ghatei<>2) and (f_sanad.BD_bs=0) and (f_tafzil.kol_n=f_sanad.kol_n) and (f_tafzil.moen_n=f_sanad.moen_n) and (f_tafzil.tafzil_n=f_sanad.tafzil_n) ) As Bs2
,(select IsNull(sum(price),0) from F_sanad
where f_sanad.ghatei<>2 and (f_sanad.date1 >='83/01/01' and f_sanad.date1<='88/01/01') and (f_sanad.BD_bs=1) and (f_sanad.typ not in(51,52,53,54,55,56) ) and (f_tafzil.kol_n=f_sanad.kol_n) and (f_tafzil.moen_n=f_sanad.moen_n) and (f_tafzil.tafzil_n=f_sanad.tafzil_n) ) As Bd_T
,(select IsNull(sum(price),0) from F_sanad
where (f_sanad.ghatei<>2) and (f_sanad.date1 >='83/01/01' and f_sanad.date1<='88/01/01') and (f_sanad.BD_bs=0) and (f_sanad.typ not in(51,52,53,54,55,56) ) and (f_tafzil.kol_n=f_sanad.kol_n) and (f_tafzil.moen_n=f_sanad.moen_n) and (f_tafzil.tafzil_n=f_sanad.tafzil_n) ) As Bs_T
,f_tafzil.tafzil_n AS Tn,f_tafzil.moen_n AS Mn
from f_tafzil
where (select count(f_kol.kol_n) from f_kol where f_kol.kol_n=f_tafzil.kol_n)>0
and (select count(f_moein.moen_n) from f_moein where f_moein.moen_n=f_tafzil.moen_n ) >0
-- where (select top 1 isnull(f_kol.kol_n,0) from f_kol where f_kol.kol_n=f_tafzil.kol_n )>0
-- and (select top 1 isnull(f_moein.moen_n,0) from f_moein where f_moein.moen_n=f_tafzil.moen_n ) >0
order by f_tafzil.kol_n,f_tafzil.moen_n,f_tafzil.tafzil_n
AminSobati
دوشنبه 02 اردیبهشت 1387, 08:11 صبح
حمید رضا جان چرا از EXISTS استفاده نمیکنین؟
حمیدرضاصادقیان
دوشنبه 02 اردیبهشت 1387, 09:15 صبح
ممنون استاد ثباتی.ولی در نتیجه کوئری که مشکلی پیش نمیاد؟
AminSobati
دوشنبه 02 اردیبهشت 1387, 09:49 صبح
منطقش رو شما بهتر میدونین، جوری بنویسین که مشکل پیش نیاد!
Microsoft.net
دوشنبه 02 اردیبهشت 1387, 21:41 عصر
طراحی دیتابیس ضعیف کار شده جانم . وگرنه این گزارشها توی سیستم مالی نباید 20 ثانیه طول بکشه !
حمیدرضاصادقیان
دوشنبه 02 اردیبهشت 1387, 22:05 عصر
محسن جان البته ببخشیدا ولی چشم بسته غیب گفتی.اینو که خودم میدونم.
چون من دارم فقط دیباگ میکنم .این کد هم من ننوشتم .تازه دارم کاری میکنم کاربر نیازی به این کد هم حذف بشه .زیرا یک عمل اضافی داره انجام میشه.
e-shahshahani
دوشنبه 02 اردیبهشت 1387, 23:49 عصر
این دستور select دارای تعدادی فیلد هست که خود اون فیلد یه دستور select هست که به ازای تک تک رکورد ها باید این select های فیلدی، انجام شود. پوست سرور کنده میشه! :عصبانی++: اگر امکانش براتون هست یک تیشه به ریشه بزنید و از بیخ درستش کنید وگرنه بدجوری وبال گردنه!:متفکر:
مثلا به جای اینکه sum ها را هر دفعه محاسبه کنید یک جدول داشته باشید که اینها را در آن ذخیره کنید و در هنگام نیاز فقط یک select از آن بزنید.
یا اینکه sum ها را بصورت inner join محاسبه کنید مثلا
SELECT c.Id, COUNT(p.xId) AS CountOfx
FROM cats AS c INNER JOIN
pros AS p ON c.Id = p.Id
WHERE c.[TypeId] = @TypeId
GROUP BY c.Id
امیدوارم کمک کرده باشم
حمیدرضاصادقیان
سه شنبه 03 اردیبهشت 1387, 07:15 صبح
ممنون.اصلا این کوئری کلا اضافه هست.به خاطر اینکه برای یک گزارش گیری ابتدا یک بار این کوئری گرفته میشه و جمع مبالغ در این جدول ریخته میشه دوباره هنگام گزارش گیری یک کوئری دیگه از روی این جدول ساخته میشه.یعنی بدبختی.
من کلا میخوام اینو حذفش کنم ولی فعلا برای اینکه کار مشتریان بیچاره راه بیافته این جوری که نوشتم درستش کردم تا بعد سر فرصت دخلشو بیارم.
بازم از همه دوستان تشکر میکنم.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.