PDA

View Full Version : انتخاب رکورد از Union دو جدول



supporter
جمعه 05 مرداد 1386, 14:28 عصر
با سلام،
فرض کنید 2 چدول داریم به نامهای Live, Archive که اطلاعات مربوط به گردش حساب ها در آن ها نگهداری می شود.در واقع جدول Live شامل رکورده های ماه جاری و جدول Archiveشامل رکوردهای ماه های قبل از ماه جاری است.
این کار برای افزایش سرعت Insert به خاطر حجم زیاد رکوردهای جدول و همچنین زیاد بودن تعداد Index های روی اون و همچنین زیاد بودن تعداد کاربرانی که به ظور همزمان با این چدول درگیر هستن انجام شده (بگذریم که اصولا استفاده از این روش برای این کار مناسبه یا نه؟)
اما سوالها :
سوال 1 : می خواهیم 50 گردش آخر یک حساب خاص رو انتخاب کنیم البته به ترتیب نزولی روی TransDate (توجه داشته باشید که Index های ما روی TransDate و ACCNo, TransDate
هر دو صعودی هستند)
نکات
- مشخصه که ممکنه تنها نعدادی از 50 رکورد مورد نظر ما در جدول Live باشن
- از آنجایی که جدول Archive نزدیک به 100 میلیون رکورد داره Query هایی شبیه




SELECT TOP 50 *
From (SEELCT * FROM Live WHERE ACCNO = @ACCNO
UNION ALL
SEELCT * FROM Archive WHERE ACCNO = @ACCNO
) T
ORDER BY TransDate DESC

به شدت کند اجرا می شن
- هدف روشی با بهترین Performance ممکنه

یه راه حل پیشنهادی چیزی شبیه کد زیره




INSERT INTO #tblTemp Select Top 50 * From Live WHERE ACCNO = @ACCNO Order BY TransDate DESC
SET @RewCount = @@RowCount
Set @Cmd = 'INSERT INTO #tblTemp SELECT TOP ' + STR (50 - @RewCount) + ' * FROM Archive WHERE ACCNO =' STR(@ACCNO) + 'Order BY TransDate DESC '
EXEC @Cmd
Select * from #blTemp

و یا اگه نخواهیم از Dynamic Query استفاده کنیم




INSERT INTO #tblTemp Select Top 50 * From Live WHERE ACCNO = @ACCNO Order BY TransDate DESC
INSERT INTO #tblTemp Select Top 50 * From Archive WHERE ACCNO = @ACCNO Order BY TransDate DESC
Select Top 50 * from #blTemp


راستش هیچ کدوم از روش های بالا به نظر خودم جالب نمی آد ممنون میشم اگه روش بهتری پیشنهاد کنید.
سوال 2 : اگه بخواهیم به جای استفاده از این روش جدول اصلی رو (که به تا جدول Live , Archive شکسته شده) Partition کنیم بهترین شیوه Partioning و اصولا هزینه های این کار به نظر شما چیه؟
ببخشید اگه یه کم سوالم طولانی شد.

AminSobati
شنبه 06 مرداد 1386, 00:20 صبح
در SQL Server 2005 با توجه به امکان Partitioning شما نیازی به دو جدول ندارید و بر اساس ماه میتونین دسته بندی کنین. اما همچنان در مورد ساخت ایندکسها باید دقت کافی داشته باشید. چون بطور پیش فرض ایندکسها هم مثل خود جدول Partition خواهند شد مگر اینکه شما غیر از این رو اعمال کنین. به تناسب نیاز Queryها، بعضی از ایندکسها خوبه Partition بشن و بعضی بهتره نشن.
اما در مورد وضعیت فعلی، من با توجه به اینکه جداول و Exec Plan رو ندارم پیشنهاد دادن Query تا حدی کورکورانه است! این رو آزمایش کنین:


SELECT TOP 50 * FROM
(SELECT * FROM
(SELECT TOP 50 * FROM Live WHERE ACCNO = @ACCNO ORDER BY TransDate DESC) sq1
UNION ALL
SELECT * FROM
(SELECT TOP 50 * FROM Archive WHERE ACCNO = @ACCNO ORDER BY TransDate DESC) sq2
) sq3 ORDER BY TransDate DESC