2013-08-30 139 views
3

的情況下,我有一個簡單的查詢優化的問題,它是SQL查詢性能的簡單聯合

才能提高鑑於其具有定義的性能

SELECT * FROM A UNION ALL SELECT * FROM B

,這是執行如此糟糕,它需要12秒的6.5k記錄

任何幫助表示讚賞。

+0

您可以使用左外Joiun.It會及時給您下降,性能好。 – Sasidharan

+1

@UpvoteMarkAnswer:這將給我只有左表的記錄,更多假設我不能更改此查詢, –

+0

從A選擇*多久?從B選擇*多久? A和B中的數據類型是否相似(沒有隱式轉換髮生)? – zedfoxus

回答

1

有沒有理由讓這兩個不在同一張桌子上,無論你做什麼,最終都會是可怕的。如果可能,考慮遷移到一個表。如果沒有,你可以通過將它們全部插入同一個東西來「實現一個視圖」。


他這樣說,你是不是將要選擇*上的聯盟,如果有在視圖頂部的特定條件下,性能可以通過索引的列提高。

如果你告訴大家這是什麼特定的數據庫會有所幫助。

0

我最好的建議是將從源表返回的數量或記錄限制爲您真正需要的數量,並確保您的數據正確編入索引。

不要使用*,除非它是一個專門的腳本(即使這樣做仍然會列出列更好),只包括您真正需要的列。

根據最常用的查詢使用適當的索引。刪除所有未使用的索引。刪除任何重複的索引。

Pluralsight在MS SQL Server查詢性能調優方面擁有精彩的課程。 http://www.pluralsight.com/training/Courses/TableOfContents/query-tuning-introduction

該課程由Vinod Kumar和Pinal Dave介紹,他們是兩位非常出色的人士。

您還可以查看Pinal關於SQL Server性能的文章,以幫助指出您可能沒有想過的領域。

http://blog.sqlauthority.com/sql-server-performance-tuning/

+0

感謝您的評論。 :)會參考 –

4

union鑑於這樣的問題是,該表的原始列將不通過視圖優化訪問的,所以當你使用的看法是這樣的:

select * from myview where foo = 5 

where子句是由視圖遞送的整個行集一個濾波器,所以所有行來自兩個表的都經過聯合處理,所以不會使用索引。

有過一次表現任何希望,你必須以某種進去你想狀況視圖,並應用到每個表,但保持它的變量,因此您可以在使用它適用不同的標準。

我找到了一個工作,圍繞這一點。這有點冒險,並不適合併發使用,但它的工作原理!試試這個:

create table myview_criteria(val int); 
insert into myview_criteria values (0); -- it should have exactly one row 

create view myview as 
SELECT * FROM A 
WHERE foo = (select val from myview_criteria) 
UNION ALL 
SELECT * FROM B 
WHERE foo = (select val from myview_criteria); 

然後使用它:

update myview_criteria set val = 5; 
select * from myview; 

假設有上foo的指數,該指數將被使用。

這裏提醒一下,因爲很明顯,當多個處決同時進行此技術將無法工作。