PDA

View Full Version : مقایسه 2 query



titbasoft
شنبه 03 اردیبهشت 1384, 13:48 عصر
کدامیک از دو query زیر رو پیشنهاد می کنید.


SELECT fname,1 status FROM t1 WHERE t1.cx IN (select t2.cx from t2 where t2.c1='1') AND t1.cy='v1'

UNION

SELECT fname,2 status FROM t1 WHERE t1.cx IN (select t3.cx from t3 where t3.c1='1') AND t1.cy='v2'


SELECT fname,status =
(case
when t1.cx IN (select t2.cx from t2 where t2.c1='1') AND t1.cy='v1' then 1
when t1.cx IN (select t3.cx from t3 where t3.c1='1') AND t1.cy='v2' then 2
end
) from t1

البته حالتهای شرطی ما خیلی بیشتره به عبارت دیگر در قسمت case حالتهای زیادی رو باید بررسی کنیم که بعضی هاشون نیازمند scan کردن یک جدول دیگه هم هست. علت اصلی شک من هم برای گزینه اول اینه که در گزینه دوم درسته که در query اصلی (جدول t1) یکبار scan انجام میشه اما در داخل قسمت case تعداد زیادی scan انجام میشه که مطمئن هستیم بهشون نیازی نیست. توجه کنید که در query اولی ابتدا رکورد ها محدود شده اند و بعد مثلا به تعداد نصف رکوردهای جدول t1 جدول t2 اسکن میشه و بعد باز هم به اندازه نصف رکوردهای t1 جدول t3 اسکن میشه ، این در حالی است که در query دومی به اندازه کل رکوردهای t1 جداول t2 و t3 اسکن میشن.

AminSobati
یک شنبه 04 اردیبهشت 1384, 18:54 عصر
دوست عزیزم،
بهتر بودن یکی از این دو Query، به تعریف شما از بهتر بودن برمیگرده! اگر منظورتون سرعت اجرا و کلا Performance باشه، اگرچه بدون در اختیار داشتن جداول و ندیدن Execution Plan نمیشه دقیق اظهار نظر کرد، ولی به نظر میرسه Query اول رو بشه به Join تبدیل کرد و با ایندکسهای مناسب، سرعت خوبی بدست آورد.

titbasoft
یک شنبه 04 اردیبهشت 1384, 22:36 عصر
اولا از حسن توجه شما صمیمانه ممنونم
بسیار خوب سعی می کنم سناریوی اصلی رو خدمتتون ارائه کنم.
فرض کنید یک رشته با فرمت XML داریم (doc@) به صورت زیر:

<ROOT>
<b k="1" t="1" d="2002-1-1"/>
<b k="1" t="2" d="2002-2-1"/>
<b k="2" t="1" d="2002-3-1"/>
<b k="2" t="2" d="2002-4-1"/>
<b k="3" t="1" d="2002-5-1"/>
<b k="3" t="2" d="2002-6-1"/>
</ROOT>
و به صورت زیر اون رو توی یک Temp Table ذخیره می کنیم .

DECLARE @idoc int
CREATE TABLE #temp (
k tinyint,
t int,
d datetime
)
EXEC xp_xml_preparedocument @idoc OUTPUT, @doc
INSERT INTO #temp SELECT k,t,d FROM OPENXML ('/ROOT/b',1)
(یک نکته دیگه هم که اینجا پیش میاد اینه که چطوری روی Temp Table می شه Composied PK گذاشت)
از طرفی دیگر یک جدول با STRUCTURE زیر داریم.

CREATE TABLE texts(
k tinyint ,
t int ,
bk tinyint,
bt int,
d datetime,
CONSTRAINTS PK_texts PRIMARY KEY (k,t)
)
ذکر این نکته لازم است که k و t در هر دو جدول به عنوان PK در نظر گرفته خواهند شد و برای مقایسه رکورد های دو جدول از این 2 فیلد استفاده می کنیم
2 تا متغیر هم داریم با نام های bk@ و bt@ به ترتیب از نوع های tinyint و int
حدود تعداد رکورد جدول texts در حدود 700000 رکورد و جدول temp حدود 3000 رکورد است.
حالا ما با استفاده از این دو جدول می خواهیم به result set زیر برسیم:
* 3 تا فیلد به صورت k,t و state که مقدار آن به صورت زیر مشخص می شود
رکوردهایی که در temp هستند و در text نیستند = 0
رکوردهایی که در هردو هستند اما در texts به شرط آنکه bk با bk@ و bt با bt@ برابر نباشد = 1
رکوردهایی که در هر دو هستند اما در texts به شرط آنکه bk با bk@ و bt با bt@ برابر باشد و d آنها یکی است = 2
رکوردهایی که در هر دو هستند اما در texts به شرط آنکه bk با bk@ و bt با bt@ برابر باشد و d آنها متفاوت است = 3
رکوردهایی که در text هستند و در temp نیستند و به شرط آنکه bk با bk@ و bt با bt@ برابر باشد = 4

می دونم یه مقدار وقت گیره و من هم اصل query رو نمی خوام یک solution خوب هم برام راه گشا خواهد بود.
بازم از اینکه اینقدر توجه دارید ممنونم.