0

我遇到了一个奇怪的问题。我有一个使用 4 个表的查询(抱歉拉脱维亚名称):

  • KL_PrecesIzejvielas:20 行
  • Parvietots_details:27897 行
  • Razots:282行
  • KL_Simple:25 行

表只有聚集索引(主键),没有其他索引。

我正在执行一个查询:

SELECT  KL_PrecesIzejvielas.APRAKSTS AS PreceNosauk ,
        COUNT(*) AS RazosanuSkaits ,
        SUM(SKAITS) AS Kopskaits ,
        Mervienibas.APRAKSTS AS Mervieniba
FROM    KL_Simple AS Mervienibas
        INNER JOIN ( KL_PrecesIzejvielas
                     INNER JOIN ( Parvietots_details
                                  INNER JOIN Razots ON Parvietots_details.ID_PARVIETOTS_MASTER = Razots.ID_PRECES_IEKS_KUST_ID
                                ) ON KL_PrecesIzejvielas.ID = Parvietots_details.ID_PRECE_IZEJVIELA
                   ) ON Mervienibas.ID = KL_PrecesIzejvielas.DEFAULT_MERVIENIBA
WHERE   Razots.ID_ATBILDPERSONA = 27
        AND Razots.DATUMSLAIKS >= ( SELECT TOP 1
                                            DATUMS
                                    FROM    LoginHistory
                                    WHERE   ID_USER = 27
                                    ORDER BY DATUMS DESC
                                  )
GROUP BY KL_PrecesIzejvielas.APRAKSTS ,
        Mervienibas.APRAKSTS
ORDER BY KL_PrecesIzejvielas.APRAKSTS ,
        Mervienibas.APRAKSTS

这是执行计划: 执行计划 链接到大图

查询需要 6 秒来处理!执行计划表明,最大的工作是在将大 Parvietots_details 表加入 KL_PrecesIzejvielas 时完成,并且在对“Razots”应用过滤器之前完成。这似乎是错误的。

奇怪的是,如果我只拿走 25 行的小表 KL_Simple/Mervienibas 现在的执行时间只有 126 毫秒。在对“Razots”应用过滤器之后,现在加入了大表,我认为这就是区别(?)

SELECT  KL_PrecesIzejvielas.APRAKSTS AS PreceNosauk ,
        COUNT(*) AS RazosanuSkaits ,
        SUM(SKAITS) AS Kopskaits
FROM    KL_PrecesIzejvielas
        INNER JOIN ( Parvietots_details
                     INNER JOIN Razots ON Parvietots_details.ID_PARVIETOTS_MASTER = Razots.ID_PRECES_IEKS_KUST_ID
                   ) ON KL_PrecesIzejvielas.ID = Parvietots_details.ID_PRECE_IZEJVIELA
WHERE   Razots.ID_ATBILDPERSONA = 27
        AND Razots.DATUMSLAIKS >= ( SELECT TOP 1
                                            DATUMS
                                    FROM    LoginHistory
                                    WHERE   ID_USER = 27
                                    ORDER BY DATUMS DESC
                                  )
GROUP BY KL_PrecesIzejvielas.APRAKSTS
ORDER BY KL_PrecesIzejvielas.APRAKSTS

执行计划 链接到更大的图片

减速的原因是什么?我应该重写我的查询吗?为什么查询处理器选择这样的计划?

我也尝试删除统计信息,但没有任何改善。

编辑:这里是执行计划 XML:
慢查询
快速查询

4

2 回答 2

0

由于大小/语言,很难阅读屏幕截图/SQL。看起来好像他们将您的 JOIN 构建到 KL_Simple 的方式意味着查询的其余部分正在为 KL_Simple 中的每一行重复。

于 2013-07-25T17:25:07.737 回答
0

我认为where子句和内部连接的执行顺序不会对查询性能产生任何影响。

第二个查询执行得更好的唯一原因是您从连接列表中删除了一个附加表。您仍然可以通过执行以下查询来确认这一事实。在此,我将查询与 CTE 中的 where 子句分开,然后在连接中使用它。

with Razots_CTE(ID_ATBILDPERSONA,DATUMSLAIKS,ID_PRECES_IEKS_KUST_ID)as
(select ID_ATBILDPERSONA,DATUMSLAIKS,ID_PRECES_IEKS_KUST_ID from Razots WHERE Razots.ID_ATBILDPERSONA=27 
AND Razots.DATUMSLAIKS >= (SELECT TOP 1 DATUMS FROM LoginHistory WHERE ID_USER=27 ) )

SELECT KL_PrecesIzejvielas.APRAKSTS AS PreceNosauk, 
Count(*) AS RazosanuSkaits, 
SUM(SKAITS) AS Kopskaits
FROM KL_PrecesIzejvielas INNER JOIN 
(Parvietots_details INNER JOIN 
Razots_CTE Razots
ON Parvietots_details.ID_PARVIETOTS_MASTER=Razots.ID_PRECES_IEKS_KUST_ID) 
ON KL_PrecesIzejvielas.ID=Parvietots_details.ID_PRECE_IZEJVIELA
GROUP BY KL_PrecesIzejvielas.APRAKSTS
ORDER BY KL_PrecesIzejvielas.APRAKSTS
于 2013-07-25T18:09:49.337 回答