PDA

View Full Version : مقاله : مقایسه سرعت روش های اتصال جداول رابطه ای در بانک اطلاعاتی SQLServer



ASKaffash
یک شنبه 12 شهریور 1391, 10:49 صبح
سلام
تا چند سال پیش فکر می کردم که بین سرعت اجرای SubQuery و Join و Top 1 در نوشتن یک Query اختلاف زیادی وجود ندارد در این راستا تحقیقی را بر روی یک بانک اطلاعاتی یک میلیون رکوردی به همراه یکی از همکارانم تدارک دیدم که نتیجه آن خیلی جالب بود و از آن تاریخ همیشه در بکار بردن QubQuey و Join و ... خیلی دقت می کنم (به خصوص در بانکهای اطلاعاتی بزرگ) در PDF پیوست نتیجه تحقیق را قرار میدهم انشالله برای هموطنان مفید فایده واقع گردد لطفا در صورت استفاده از این مطلب در جای دیگر حتما منبع مقاله را ذکر نمائید

baktash.n81@gmail.com
یک شنبه 12 شهریور 1391, 11:49 صبح
سلام

با احترام و تشکر از زحمات شما و همکار گرامیتون ... همونطور که می دونید Sub Query فقط اون چیزی که شما نوشتی نیست ... در واقع کد شما ...



select T1.* ,(select a1 from T2 where T2.a1=T1.a1) from t1


استفاده مناسبی از Sub Query و مثال مناسبی نیست ... به این کد یک نگاه بندازید ... اینها هم Sub Query هستند ...






SELECT

NameFROM AdventureWorks2008R2.Production.ProductWHERE ListPrice =(SELECT ListPrice FROM AdventureWorks2008R2.Production.Product WHERE Name ='Chainring Bolts')








SELECT Prd1. NameFROM AdventureWorks2008R2.Production.Product AS Prd1 JOIN AdventureWorks2008R2.Production.Product AS Prd2 ON (Prd1.ListPrice = Prd2.ListPrice)WHERE Prd2. Name ='Chainring Bolts'


و البته در خصوص Performance در سایت مایکروسافت این مطلب و نوشته ...


"Many Transact-SQL statements that include subqueries can be alternatively formulated as joins. Other questions can be posed only with subqueries. In Transact-SQL, there is usually no performance difference between a statement that includes a subquery and a semantically equivalent version that does not. However, in some cases where existence must be checked, a join yields better performance. Otherwise, the nested query must be processed for each result of the outer query to ensure elimination of duplicates. In such cases, a join approach would yield better results. The following is an example showing both a subquery SELECT and a join SELECT that return the same result set"


از ابن مطلب که بگذریم مقایسه شما زیاد منطقی نیست چون مدل SubQuery که شما نوشتی برای مواردی استفاده می شه که Join جوابگوی کار ما نیست ... و خوب مقایسه در این خصوص بی معنی می شه ... مثالا این کد با join پیاده سازی نمی شه ...


SELECT Ord.SalesOrderID, Ord.OrderDate,




(SELECT MAX(OrdDet.UnitPrice)

FROM AdventureWorks.Sales.SalesOrderDetail AS OrdDet
WHERE Ord.SalesOrderID = OrdDet.SalesOrderID) AS MaxUnitPrice
FROM AdventureWorks2008R2.Sales.SalesOrderHeader AS Ord



احتراما مثالی که شما استفاده کردی فقط یه اشتباه برنامه نویسی و نمی شه روی مقایسه حساب کرد.

ASKaffash
یک شنبه 12 شهریور 1391, 12:30 عصر
سلام
بنظرم باید با دقت بیشتری به مقاله نگاه کنید در موارد زیادی شما حق انتخاب بین SubQuery و Join دارید (در این مقاله این شرایط حاکم است) بخصوص در یک Master/Detail هنگامیکه قرار است از Detail به جدول Master دسترسی پیدا کنید در هر صورت شما هم در یک بانک حجیم تست کنید حتما به این نتیجه خواهید رسید و این تحقیق واقعی است نه تئوری روی کاغذ در ضمن در مواقعی اصلا نمی توان با Join نتیجه مورد نظر را به دست آورد (و بالعکس) این تحقیق فقط برای حالت استفاده انتخابی بین هردو روش است نه چیز دیگر در مورد نوشته آخر شما "احتراما مثالی که شما استفاده کردی فقط یه اشتباه برنامه نویسی و نمی شه روی مقایسه حساب کرد." که اصلا مفهوم نیست.

baktash.n81@gmail.com
یک شنبه 12 شهریور 1391, 13:24 عصر
ببینید ... اگه Sub Query در قسمت where قرار بگیرد مثل مثالی که در بالا زدم حالتیست که هم با Join قابل پیاده سازیست و هم با Sub Query ... اینو که قبول دارید ؟!

اما مثالی که شما زدید یه انتخاب نیست چون ما مواقعی Sub Query رو توی لیست Select ها قرار می دیم که مجبور باشیم این کارو انجام بدیم کی مجبور می شیم مثالا همون جدول Master-Detail رو در نظر بگیرید می خوایم به ازای هر رکورد از جدول مستر می خوایم رکوردی از جدول Detail روبیاریم که Max یه مقداری رو داشته باشه ... در اینصورت Join نمی تونه این کارو برامون انجام بده ... پس مجبوریم از SubQuery درون لیست Select استفاده کنیم ... و شما اینو باهم مقایسه کردید ... که منطقی نیست برای اینکه اصلا Join نمی تونه اینکارو بکنه ...

در حالتی که شما SubQuery رو درون Select قرار بدید و واقعا نیازی به این کار نباشه شما یه اشتباه برنامه نویسی انجام دادید ...

اگه شما می خواین این نوع SubQuery رو رو از نظر Performance با چیزی مقایسه کنید می تونید با استفاده از تابع یا استفاده از Cross Apply مقایسه کنید ...

ASKaffash
یک شنبه 12 شهریور 1391, 14:04 عصر
سلام دوست عزیر
ببینید به مثال ذیل نگاه کنید : (M=Master و D=Detail)
Select D.*,M.m1
From D
Left Join M On M.Key=D.Key
Where D.d1=... and M.m2=... and ...
این یک Master/Detail است که با Join پیاده سازی شده و شرط های Where نیز بدون SubQuery است
ولی مثال ذیل همان Master/Detail است که با SubQuery پیاده سازی شده است
Select D.*,m1=(Select m1 From M Where M.Key=D.Key)
From D
Where D.d1=... and (Select m2 From M Where M.Key=D.Key)=... and ...
پس لزوما حتما نباید با توابع جمعی مثل Sum طرف باشیم اگر قرار است از Sum یا Count استفاده کنیم اصلا با Join شدنی نیست
(دقت شود : مقاله برای حالتی است که هر دوروش را میتوان بکار برد برای توابع جمعی باید از SubQuery استفاده کرد)

baktash.n81@gmail.com
یک شنبه 12 شهریور 1391, 14:21 عصر
من نمی گم مثال شما شدنی نیست ... شدنیه ولی استفاده اشتباه از Sub Query هست ... شما کل تحقیق تون رو روی مثال اشتباه قرار دادین خوب معلومه که یابد تفاوت زیادی وجود داشته باشه ...

برای اینکه به ازای هر رکورد از Select بیرونی یه بار Select درونی انجام می شه که اصلا نیازی به اینکار نیستو این اشتباه برنامه نویسیه ...

ASKaffash
دوشنبه 13 شهریور 1391, 07:22 صبح
سلام دوست عزیز
اتفاقا خیلی زیاد این موضوع وجود دارد من 22 سال است که در کشور تولید نرم افزار می کنم و درجائی کار میکنم که داده های بسیار حجیمی دارد (بالای 50 میلیون رکورد اطلاعاتی) از طرفی خیلی زیاد بانک اطلاعاتی حجیم دیگران را دیده ام (از اراکل و اس کیوال سرور و اکسس و فاکس و پاراداکس و ...)که به این نکته دقت نمی شود وقتی نرم افزارها داده هایشان زیاد می شود کاملا اختلاف مشهود است مثال بارز این موضوع در سیستم حسابداری برای جدول کالا / فاکتور / اقلام فاکتور است اگر خواستید واقعی آن را ارائه می دهم من این تحقیق را به علت وجود موضوع واقعی پیگیری کردم نه فقط یک تئوری برای شرایط خاص (مثال کندی در حسابداری هائی که شما هم می شناسید و نام بردن آن مجاز نیست همین موارد هم است) در ضمن در مثال قبلی من جای M و D وارونه بود که اصلاح کردم(با معذرت)
در پست ذیل همین اتفاق در حال وقوع است :
http://barnamenevis.org/showthread.php?359338-راهنمایی-برای-گرفتن-Query-از-این-اطلاعات....

baktash.n81@gmail.com
دوشنبه 13 شهریور 1391, 09:03 صبح
خوب این حرف شما رو قبول دارم ... اما در شرایطی Performance این دو باهم برابره ... ! شما توی تحقیقتون خیلی قطعی برخورد کردین نوع ها مختلف Sub Query رو در نظر نگرفتن ... و از نوعی Sub Query استفاده کردین که زمانی که Join به دردمون نمی خوره باید ازش استفاده کنیم ...

ASKaffash
سه شنبه 14 شهریور 1391, 07:11 صبح
سلام
نه منظور در مقاله فقط شرایط مشابه آزمایش است (اتفاقا در پروژه های واقعی خیلی زیاد است) و در شرایط توابع جمعی اصلا موضوع مقاله قابل اجرا نیست در مورد حق انتخاب بین دو روش با قاطعیت اعلام کردم Join استفاده شود