2016-11-25 182 views
-1

我的查詢是:SQL IN子句替換臨時表

Select * 
from Person 
where KV_CODE IN('','',''......1000 values here) 

如何在臨時表中寫入值列表,這樣我可以用加入替換IN子句來提高性能。

此值的列表是基於用戶隨機選擇而存儲在Java集合中的。

+0

您可以使用'SELECT'作爲內部查詢來檢索這些值。 –

+0

標記您正在使用的dbms。性能問題通常是特定於產品的,因爲不同的產品具有不同的優化技術 – jarlh

+0

DBMS SQL SERVER,也標記爲 –

回答

0
select * 
from Person 
where KV_CODE in (
    select KV_CODE 
    from TempTable 
) 

這將比較Person的KV_CODE和TempTable的KV_CODE。如果有匹配,它將與它們相交,這意味着你的第一個選擇只會打印那些行。

select * 
from Person p 
join TempTable tmp 
on p.KV_CODE = tmp.KV_CODE 

這將連接兩個表並顯示兩個表中的匹配行。

除非你的問題是

+0

是的,你說得對Fredrik,我的問題是如何從java集合中填充臨時表。 –

0
Select * from Person P INNER JOIN #Temp T ON T.KV_CODE = P.KV_CODE 

「如何從Java集合一個臨時表」可以在類似於常規表臨時表申請INNER JOIN

0

較新的數據庫解決方案已經優化了這一點。 IN子句和Join之間沒有太大的區別,因爲優化器會計算出此方面並通過適當的路徑執行查詢。

如果你仍然希望,這是你必須做的。 如果您使用的是Oracle,

  1. 您可以創建一個會話範圍或交易範圍的臨時表。
  2. 將數據插入到該臨時表
SELECT * 
FROM PERSONS T1, 
    TEMP_TABLE_NAME_HERE T2 
WHERE T1.KV_CODE = T2.KV_CODE 

消防查詢然而,更好的解決方法是避免在運行時臨時表創建。實際上,您可以在應用程序數據庫中創建一個永久表,並使用一些唯一鍵來標識會話(以隔離跨會話影響,即2個使用相同功能的用戶)。

CREATE TABLE KV_TEMP_TABLE 
(SESSION_ID VARCHAR2(100), 
KV_CODE VARCHAR2(100) 
); 

- 調整數據類型適當

然後將查詢應該像

SELECT * FROM PERSONS T1, KV_TEMP_TABLE T2 
WHERE T2.SESSION_ID = ? 
AND T1.KV_CODE = T2.KV_CODE 

--bind會話ID 發佈此查詢之前,你必須用正常數據填充到KV_TEMP_TABLE插入語句(連同會話ID)。

+0

其實我的項目使用舊版本的SQL SERVER,因爲IN子句中的長列表導致查詢處理器內存異常運行。爲了避免這種情況,我必須用加入 –

+0

@ManishKapasiya替換IN,哦!這就說得通了。然後我會建議採用上面建議的方法2。如果值太多,可以考慮增加索引來提高性能。 –

0

使用這個例子來填充臨時表:

DECLARE @t TABLE 
(
EmployeeID INT, 
Certs VARCHAR(8000) 
) 
INSERT @t VALUES (1,'B.E.,MCA, MCDBA, PGDCA'), (2,'M.Com.,B.Sc.'), (3,'M.Sc.,M.Tech.') 

SELECT EmployeeID, 
LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS Certs 
FROM 
(
SELECT EmployeeID,CAST('<XMLRoot><RowData>' + REPLACE(Certs,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x 
FROM @t 
)t 
CROSS APPLY x.nodes('/XMLRoot/RowData')m(n) 

一旦臨時表@t被填充,它可以用來使用連接以獲得所需的輸出。