PDA

View Full Version : subquery های وابسته



ali_mnkt
پنج شنبه 29 دی 1390, 14:35 عصر
سلام به دوستان

من با subquery های وابسته مشگل دارم و نمی دونم که چطوری اجرا می شن به عنوان مثال subquery های غیر وابسته به این شکل هستند که اول subquery اجرا می شه و سپس نتیجه رو ( که می تونه یک سطر یا چند سطر باشه ) رو به query پدر می فرسته حالا اگه ممکنه یکی با یک مثال که روی دو جدول انجام می شه نحوه اجرا شدن این نوع از query ها رو توضیح بده

یوسف زالی
پنج شنبه 29 دی 1390, 15:24 عصر
سلام.
شما طبق سند خاصی می گی اول ساب کوئری اجرا می شه؟

ali_mnkt
پنج شنبه 29 دی 1390, 22:27 عصر
سلام.
شما طبق سند خاصی می گی اول ساب کوئری اجرا می شه؟
سلام دوست عزیز
به عنوان مثال این query رو ببینید


select *
from [order]
where pid =(select pid from product where pname='tea')

خوب تو این query که یک query تو در تو از نوع غیر وابسته است اول query داخلی اجرا می شه و بعد جواب در اختیار query بیرونی قرار می گیره . جالا سئوال من روی query های وابسته است که به چه صورت انجام می شن ؟

یوسف زالی
پنج شنبه 29 دی 1390, 22:45 عصر
دقیقا نمی دونم که اونچه که ما تصور می کنیم درست هست یا نه.
اما به نظر منطقی میاد که طوری باشه که شما می گی.
اما می دونم که پردازش معنوی در اس کیو ال وجود نداره و پیاده سازی نشده. لااقل تا جایی که من خبر دارم.
برای مثال کوئری زیر رو در نظر بگیرید:
select distinct F from TBL1 cross join TBL2
اگر فیلد F در هر دو این جداول باشه که اروره.
اما اگر در یکی از اونها باشه نیازی به join کردن نیست. اما متاسفانه این اتفاق می افته.
به همین خاطر من اون مورد از حرفهاتون رو تایید نمی کنم.
اما می دونم که در سلکت در حقیقت برای هر ردیف یک بار پروسه احرا می شه:
select 1 from TBL
به تعداد ردیف های شما 1 میاره.
و به طور مشابه :
select * from TBL where exists(select * from TBL2 where TBL.F = TBL2.X) -- sql
می باید برای هر ردیف یک بار ارزیابی بشه.

ali_mnkt
شنبه 01 بهمن 1390, 00:18 صبح
دقیقا نمی دونم که اونچه که ما تصور می کنیم درست هست یا نه.
اما به نظر منطقی میاد که طوری باشه که شما می گی.
اما می دونم که پردازش معنوی در اس کیو ال وجود نداره و پیاده سازی نشده. لااقل تا جایی که من خبر دارم.
برای مثال کوئری زیر رو در نظر بگیرید:
select distinct F from TBL1 cross join TBL2
اگر فیلد F در هر دو این جداول باشه که اروره.
اما اگر در یکی از اونها باشه نیازی به join کردن نیست. اما متاسفانه این اتفاق می افته.
به همین خاطر من اون مورد از حرفهاتون رو تایید نمی کنم.
اما می دونم که در سلکت در حقیقت برای هر ردیف یک بار پروسه احرا می شه:
select 1 from TBL
به تعداد ردیف های شما 1 میاره.
و به طور مشابه :
select * from TBL where exists(select * from TBL2 where TBL.F = TBL2.X) -- sql
می باید برای هر ردیف یک بار ارزیابی بشه.

خوب دوست عزیز در همین query نحوه ارزیابی چطوریه ؟ آیا به ازای هر ردیف از TBL می یاد برسی می کنه که در select داخلی با شرطی که داره وجود داره یا روش دیگه ای محاسبات انجام می شه ؟

یوسف زالی
شنبه 01 بهمن 1390, 00:25 صبح
تا جایی که من در این زمینه اطلاع دارم همون روشی هست که عرض کردم.
به ازای هر ردیف یک بار شرط ها چک می شه.
یک بار برای ردیف اول ساب کوئری تست می شه، یک بار برای ردیف دوم و ...
اگر روش جدیدی وجود داره بفرمایید تا ما هم در این زمینه بروز بشیم.
:چشمک:

baktash.n81@gmail.com
شنبه 01 بهمن 1390, 08:28 صبح
سلام ...

دوستان به نظر میاد که SQL این مدل subquery ها را به وسیله Join شبیه سازی می کنه ... درسته شما این رو به صورت Select تو در تو می نویسید اما SQL اول Select درونی را به دست میاره بعد نتیجه رو با جدول بیرونی Join می کنه ... خودتون هم اگه کد رو یه بار به صورت Join بنویسید و Execution Plan رو نگاه کنید می بینید که نتیجه دوتا Query یکسان می شه ...

اما در برخی Query ها روش دوم اتفاق می افته یعنی به ازای هر سطر Query بیرونی یه بار Query درونی اجرا می شه ... مثل این Query


Select f1,(Select f2 from t2 where f3=tt.f3)from t1 as tt


این دیگه بستگی به کد و نتیجه مورد نیاز داره که کدام روش رو انتخاب کنید

ali_mnkt
شنبه 01 بهمن 1390, 14:24 عصر
سلام ...

دوستان به نظر میاد که SQL این مدل subquery ها را به وسیله Join شبیه سازی می کنه ... درسته شما این رو به صورت Select تو در تو می نویسید اما SQL اول Select درونی را به دست میاره بعد نتیجه رو با جدول بیرونی Join می کنه ... خودتون هم اگه کد رو یه بار به صورت Join بنویسید و Execution Plan رو نگاه کنید می بینید که نتیجه دوتا Query یکسان می شه ...

اما در برخی Query ها روش دوم اتفاق می افته یعنی به ازای هر سطر Query بیرونی یه بار Query درونی اجرا می شه ... مثل این Query


Select f1,(Select f2 from t2 where f3=tt.f3)from t1 as tt


این دیگه بستگی به کد و نتیجه مورد نیاز داره که کدام روش رو انتخاب کنید

مرسی از نظرت
اما تا اونجا که من می دونم زیر query های وابسته به این صورت عمل می کنن که ابتدا مقداری از query بیرونی به query داخلی فرستاده می شه و query داخلی هم بر اساس اون مقدار پردازشی رو انجام می ده و خروجی رو به query بیرونی می فرسته . به این query که از دیتابیس northwind هست نوجه کنید که اولین تاریخ خرید ثبت شده برای هر مشتری رو بر می گردونه :


SELECT o1.CustomerID, o1.OrderID, o1.OrderDate
FROM Orders o1
WHERE o1.OrderDate = (SELECT Min(o2.OrderDate)
FROM Orders o2 WHERE o2.CustomerID = o1.CustomerID)
ORDER BY CustomerID


تو این query معلومه که اول از query خارجی customerID به query داخلی فرستاده می شه و بعد در query داخلی اولین زمان خرید پیدا می شه و به query بیرونی فرستاده می شه . این روند به ازای تمام customerId ها انجام می شه ، اما مشگل من در روند اجرای این نوع query ها به صورت مرحله به مرحله است . مثلا آیا query بیرونی می یاد رکورد به رکورد customerId ها رو به داخلی می فرسته یا کار دیگه ای داره انجام می شه ؟

یوسف زالی
شنبه 01 بهمن 1390, 16:07 عصر
ببینید نظری که من دادم روی تجربه من از کوئری زیر هست و یادم بود که در درس پایگاه داده توزیع شده هم در مقایسه ای که بین اس کیو ال و اوراکل انجام شد عدم تحلیل معنایی جزو معایب اس کیو ال برشمرده شد.
این هم نمونه کوئری:
declare @x varchar(1000) -- sql
set @x = '' -- sql
select @x += F
from TBL

در اینجا به نظر می رسه که خاصیتی گردشی وجود داره و بر همین اساس نتیجه گرفتم که می باید به ازای هر ردیف داده، (و از حرفهای استاد فارغ از نوع کوئری) باید یک بار کوئری پردازش بشه.
سعی می کنم منابعی رو در این زمینه پیدا کنم و بگذارم.

baktash.n81@gmail.com
دوشنبه 03 بهمن 1390, 07:25 صبح
خیلی ممنون از دوستان ...

در هر صورت اگه SubQuery وابسته به Query بیرونی نباشه ... مثلا

Select * From T1 where f1 in (Select F1 from t2)


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