优化此SQL查询的最佳方法

时间:2015-10-08 16:26:07

标签: sql sql-server optimization

我必须优化这个查询,我真的很匆忙。以下查询按客户端搜索。输入值RIF.keyvaluechar LIKE 'V%10553790 '是因为在数据库中的一些旧寄存器中,当丢失字符时,一些ID曾经是V0012345678,但它应该是V12345678,因为这是ID可以具有的最大字符数。我知道12345678应该是数字而V是char然后比较,但这是另一个问题。

无论如何,查询是这样的:

SELECT DISTINCT idata.itemnum AS [ID], 
                LTRIM(RTRIM(ISNULL(CONTRATO.keyvaluechar,'N/A'))) AS [Contrato],
                idata.datestored AS [Fecha], 
                NUMERO.keyvaluesmall AS [Numero], 
                TIPO.keyvaluechar AS [Tipo], 
                LTRIM(RTRIM(ISNULL(LC.lifecyclename,'N/A'))) AS [Flujo], 
                LTRIM(RTRIM(ISNULL(LC.lcnum,-1))) AS [FlujoID], 
                LTRIM(RTRIM(ISNULL(LCS.statename,'N/A'))) AS [Cola], 
                LTRIM(RTRIM(ISNULL(LCS.statenum,-1))) AS [ColaID], 
                CASE 
                    WHEN PC.NombreProceso IN('PTD','PV2','PV3') THEN 1 
                    ELSE 0 
                END AS [Portada] 
FROM OnBase.hsi.itemdata idata WITH (NOLOCK) 
    INNER JOIN OnBase.hsi.keyitem109 TIPO WITH (NOLOCK) ON TIPO.itemnum = idata.itemnum 
    INNER JOIN OnBase.hsi.keyitem113 NUMERO WITH (NOLOCK) ON NUMERO.itemnum = idata.itemnum 
    LEFT JOIN OnBase.hsi.keyitem132 CONTRATO WITH (NOLOCK) ON CONTRATO.itemnum = idata.itemnum 
    LEFT JOIN OnBase.hsi.keyitem114 CLIENTE WITH (NOLOCK) ON CLIENTE.itemnum = idata.itemnum 
    LEFT JOIN OnBase.hsi.keyitem111 RIF WITH (NOLOCK) ON RIF.itemnum = idata.itemnum 
    INNER JOIN OnBase.hsi.doctype DOC WITH (NOLOCK) ON DOC.itemtypenum = idata.itemtypenum 
    INNER JOIN BD_WorkFlow.dbo.BBVA_ProcesosConfig PC WITH (NOLOCK) ON PC.ID_Documento = idata.itemtypenum 
    LEFT JOIN Onbase.hsi.itemlc ILC WITH (NOLOCK) ON ILC.itemnum = idata.itemnum 
    LEFT JOIN Onbase.hsi.lcstate LCS WITH (NOLOCK) ON LCS.statenum = ILC.statenum 
    LEFT JOIN Onbase.hsi.lifecycle LC WITH (NOLOCK) ON LC.lcnum = ILC.lcnum 
WHERE PC.NombreProceso <> 'XXX' AND 
      PC.NombreProceso NOT IN('PTD','PV2','PV3') AND 
      TIPO.keyvaluechar = 'CCD' AND 
      RIF.keyvaluechar LIKE 'V%10553790 '

你可以看到它是这样的,所以它找到了V0012345678或V12345678,但这不是正确的方式,或者我觉得这是最好的优化,虽然我不是数据库方面的专家。

无论如何,我有点像这样而不是最后一行

AND LEFT ('RIF.Keyvaluechar, 1) ="V"
AND SUBSTRING (RIF.Keyvaluechar, 2, LEN(RIF.Keyvaluechar)) = "12345678"

你们觉得怎么样?还有其他更好的方法来改进吗?

2 个答案:

答案 0 :(得分:2)

首先,您的查询存在逻辑问题。你有这个:

<script type="text/javascript">
 $(document).on('focus', '.form_datetime', function () {
    $(this).datetimepicker({
        weekStart: 1,
        todayBtn: 1,
        autoclose: 1,
        todayHighlight: 1,
        startView: 2,
        forceParse: 0,
        showMeridian: 1,
        format: 'mm/dd/yyyy HH:ii P',
        startDate: new Date
    });
 });
</script>

然后在你的LEFT JOIN OnBase.hsi.keyitem111 RIF WITH(NOLOCK) ON RIF.itemnum = idata.itemnum 子句中

where

将过滤器放在AND RIF.keyvaluechar LIKE 'V%10553790 ' 子句中会有效地将左连接更改为内连接。要解决此问题,请将过滤器移动到连接。

在优化它方面,我认为这意味着让它运行得更快。您正在考虑的内容可能会减慢速度,因为您正在过滤函数结果而不是字段。无论你多么忙碌,一个更好的方法是查看数据库中的索引并尝试过滤这些索引。事实上,添加新的可能是合适的。

答案 1 :(得分:1)

Keyvaluechar始终是第二个字符开头的数字,您希望将其视为数字(=删除前导零)。您可以尝试将持久列outer apply添加到表中,然后将其编入索引,并将其用作搜索条件。至少我认为应该有很多帮助。

除此之外,查看统计信息IO输出也可能是一个好主意,看看哪个表实际负责最大的I / O数量。

请注意,我希望你也知道使用NOLOCK会导致你的问题。