2017-09-27 73 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