2017-09-27 72 views
0

我在一個巨大的SQL Server表上有一個性能問題。我們有這個疑問:SQL Server查詢性能替代(在LIKE狀態員中連接字符串)

條件後
SELECT cycle 
     FROM product AS pr 
     INNER JOIN productdetails AS prd 
      ON prd.label = 'XRT354511' 
      AND (pr.cycle = prd.cycle OR prd.cycle LIKE pr.cycle+ '-EXECUTED%') 

OR語句使用喜歡來連接與-EXECUTED產品表週期(我們不關心週期「-EXECUTED」的位置,我們只需要知道,如果循環包含-EXECUTED)。

然後,我的建議來解決這個問題是改變這個一個查詢:

SELECT cycle 
    FROM product AS pr 
    INNER JOIN productdetails AS prd 
     ON prd.label = 'XRT354511' 
     AND (pr.cycle = prd.cycle 
      OR (pr.cycle = prd.cycle AND pr.cycle LIKE '-EXECUTED%')) 

當我執行的第二個查詢,它運行非常快,平穩。

我的建議是否有效?我可以使用我的建議並獲得與第一個查詢相同的結果嗎?

感謝

+3

邏輯在我看來不同。也許你應該包含一些實際的數據,這樣我們可以看到如何改進第一個查詢。如果第二個查詢返回相同的結果並且性能更好,那麼當然使用它。 –

+3

這些查詢將返回兩個不同的結果 –

+0

您確定查詢返回相同的結果集嗎?我會非常小心括號和AND/OR運算符。 –

回答

1

你能不能改變OR部分與這一個?

OR (pr.cycle = LEFT(prd.cycle, LEN(pr.cycle)) AND prd.cycle LIKE '%-EXECUTED%') 
1

您的問題:「我的建議是否有效,我可以使用我的建議並獲得與第一個查詢相同的結果嗎?」

不,它們不一樣。 讓我們重新編寫兩個查詢在下面的方式,所以我們可以集中精力參加條件:

SELECT cycle 
FROM product AS pr 
INNER JOIN productdetails AS prd ON pr.cycle = prd.cycle OR prd.cycle LIKE pr.cycle+ '-EXECUTED%' 
WHERE prd.label = 'XRT354511' ; 

SELECT cycle 
FROM product AS pr 
INNER JOIN productdetails AS prd ON pr.cycle = prd.cycle 
     OR (pr.cycle = prd.cycle AND pr.cycle LIKE '-EXECUTED%') 
WHERE prd.label = 'XRT354511' ; 

第一個條件是

pr.cycle = prd.cycle OR prd.cycle LIKE pr.cycle+ '-EXECUTED%' 

第二個(你的建議)是

pr.cycle = prd.cycle 
    OR (pr.cycle = prd.cycle AND pr.cycle LIKE '-EXECUTED%') 

後者相當於

pr.cycle = prd.cycle OR pr.cycle LIKE '-EXECUTED% 

正如你在這個簡單的形式很容易地看到,在第一你看如(。如果pr.cycle ='100')'100'和'100-EXECUTED%'。如果你發佈樣本數據,我可以試着看到你的結果,並嘗試分析性能。如果你發佈樣本數據,我可以試着看你的結果,並嘗試分析性能。

0

回答你的第一個問題是NO,你的解決方案將得到diiferent的結果比原來的查詢

優化你應該分析哪些指標對你的產品和產品詳細表主動查詢..

你可以試試;

SELECT cycle 
FROM product AS pr 
INNER JOIN productdetails AS prd ON pr.cycle = prd.cycle 
WHERE prd.label = 'XRT354511' 

UNION ALL 

SELECT cycle 
FROM product AS pr 
INNER JOIN productdetails AS prd 
ON SUBSTRING(prd.cycle, 1, LEN(pr.cycle)+9) COLLATE LATIN1_GENERAL_BIN = (pr.cycle + '-EXECUTED') COLLATE LATIN1_GENERAL_BIN 
WHERE prd.label = 'XRT354511' 
AND pr.cycle <> prd.cycle 

這將在兩個查詢它分割,第一可能會使用的指標,第二個應該是輕微的快那麼像操作

但你也告訴的"-EXECUTED"的位置不應該是很重要在productdetails.cycle

在這種情況下,你需要改變的條件二號加盟

ON prd.cycle COLLATE LATIN1_GENERAL_BIN LIKE (pr.cycle + '-%-EXECUTED%') COLLATE LATIN1_GENERAL_BIN 

請注意"-%""-EXECUTED"

之前還要注意第二個查詢的最後一個條件,你可以嘗試用一個簡單的UNION改變UNION ALL和刪除AND pr.cycle <> prd.cycle