簡體   English   中英

調整SQL選擇

[英]Tuning SQL Select

我對優化的SQL Select不太了解,我的查詢非常慢。 也許您有一些提示可以使我的查詢更快。

SQL查詢

SELECT DISTINCT CLI.FANTASIA AS Cliente
            ,   DBSMP.VEICULO_PLACA AS Placa
            ,   DBSMP.DTINICIOPREV AS 'Data Inicio Previsto'
            ,   DBSMP.DTFIMPREV AS 'Data Fim Previsto'
            ,   DBSMP.DTINICIOREAL AS 'Data Incio Real'
            ,   DBSMP.DTFIMREAL AS 'Data Fim Real'
            ,   DBSMP.CIDADE_DES AS 'Cidade Destino'
            ,   DBSMP.CIDADE_ORI AS 'Cidade Origem'
            ,   TRA.FANTASIA AS Transportador
FROM DBSMP_WORK WORK
INNER JOIN DBSMP ON WORK.ID_SMP = DBSMP.ID_SMP
INNER JOIN DBCLIENTE CLI ON DBSMP.ID_CLIENTE = CLI.ID_CLIENTE
LEFT JOIN DBCLIENTE TRA ON DBSMP.ID_TRANSPORTADOR = CLI.ID_CLIENTE
WHERE WORK.[status] IN ('F')
    AND DBSMP.ID_CLIENTE IN (85, 107, 137, 139, 510, 658, 659, 661, 702)
    AND TRA.RAZAO = 'Google'
    AND DBSMP.DTINICIOPREV BETWEEN '01/01/1900' AND '02/09/2013'

然后,我的問題是:如何使上查詢更快?

此查詢必須在SQL Server實例中運行。

提前致謝。

只是一些想法:

  • 盡量不要使用DISTINCT ,而應適當限制數據。
  • 盡量不要使用IN ,例如IN('F')可以為='F'
  • 閱讀有關索引的信息,並為要查詢/加入的列創建索引
  • 閱讀如何創建和閱讀執行計划以找到瓶頸

試試這個-

SELECT DISTINCT CLI.FANTASIA AS Cliente
            ,   DBSMP.VEICULO_PLACA AS Placa
            ,   DBSMP.DTINICIOPREV AS [Data Inicio Previsto]
            ,   DBSMP.DTFIMPREV AS [Data Fim Previsto]
            ,   DBSMP.DTINICIOREAL AS [Data Incio Real]
            ,   DBSMP.DTFIMREAL AS [Data Fim Real]
            ,   DBSMP.CIDADE_DES AS [Cidade Destino]
            ,   DBSMP.CIDADE_ORI AS [Cidade Origem]
            ,   TRA.FANTASIA AS Transportador
FROM (
    SELECT *
    FROM DBSMP
    WHERE DBSMP.DTINICIOPREV BETWEEN '19000101' AND '20130902'
        AND DBSMP.ID_CLIENTE IN (85, 107, 137, 139, 510, 658, 659, 661, 702)
) DBSMP
JOIN DBCLIENTE CLI ON DBSMP.ID_CLIENTE = CLI.ID_CLIENTE
JOIN DBCLIENTE TRA ON DBSMP.ID_TRANSPORTADOR = TRA.ID_CLIENTE -- or TRA.ID_TRANSPORTADOR = CLI.ID_CLIENTE
WHERE TRA.RAZAO = 'Google'
    AND EXISTS(
        SELECT 1 
        FROM DBSMP_WORK WORK
        WHERE WORK.ID_SMP = DBSMP.ID_SMP
            AND WORK.[status] = 'F'
    )

首先,您不需要最終的LEFT JOIN WHERE子句中的條件為TRA.RAZAO = 'Google' 這樣可以將LEFT JOIN轉換為內部LEFT JOIN

不過,最重要的是join條件:

LEFT JOIN DBCLIENTE TRA ON DBSMP.ID_TRANSPORTADOR = CLI.ID_CLIENTE

換句話說,您的查詢沒有任何意義。 您正在加入一個沒有對該表的引用的表。 我不確定正確的解決方法是什么,因為您沒有提供足夠的信息。 我最好的猜測是,這就是您對from子句的意思:

FROM DBSMP_WORK WORK 
INNER JOIN DBSMP ON WORK.ID_SMP = DBSMP.ID_SMP
INNER JOIN DBCLIENTE CLI ON DBSMP.ID_CLIENTE = CLI.ID_CLIENTE
LEFT JOIN DBCLIENTE TRA ON TRA.ID_TRANSPORTADOR = CLI.ID_CLIENTE

確保在其各種表的ID_SMPID_CLIENTEID_TRANSPORTATOR列上都有索引。 這將使加入操作更快。 然后,要完成此操作,您也可以嘗試在WHERE子句中為STATUSRAZAODTINICIOPREV列建立索引。

您的M $工具應具有查詢分析器/解釋工具,該工具可向您顯示聯接和表達式及其“成本”-在改進語句時可在迭代過程中使用它。

向參與join子句或where子句的列添加索引

嘗試刪除所有選中的列,並用“ 1”替換(-> SELECT 1 FROM ..)-如果數據集太大,這將向您顯示

嘗試刪除DISTINCT,因為它按價值進行了昂貴的分組

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM