查询执行需要更多时间,且带有独特和顶部子句

时间:2019-02-17 11:22:43

标签: sql-server-2008 query-optimization union-all

我有2个表,在过程中结合了union all运算符。第一个表包含2000万条记录,第二个表包含100万条记录。 如果我单独使用Top子句而不使用distinct子句,它会提供输出,但是当我将TOP子句与Distinct子句一起使用时,在执行未完成的查询之后,它非常快地返回前800条记录。同时使用这两种方法是否正确(Distinct和Top )在同一查询中?

SELECT Distinct TOP 1000
            TP.F_PRODUCT AS ID,
            TP.F_PRODUCT_NAME AS [NAME],
            TP.F_LANGUAGE AS LANGCODE,
            TP.F_FORMAT AS FMTCODE,
            TP.F_CUSTOM1 AS TN,
            TP.F_CUSTOM2 AS CP,
        FROM 
            T_PDF TP WHERE TP.F_PRODUCT <>''
    UNION ALL

    SELECT Distinct TOP 1000
            TP.F_PRODUCT AS ID,
            TP.F_PRODUCT_NAME AS [NAME],
            TP.F_LANGUAGE AS LANGCODE,
            TP.F_FORMAT AS FMTCODE,
            TP.F_CUSTOM3 AS TN,
            TP.F_CUSTOM4 AS CP,
        FROM 
            T_HTML TP WHERE TP.F_PRODUCT <>''

1 个答案:

答案 0 :(得分:1)

使用TOPDISTINCT并没有什么问题,而与UNION ALL的构造无关。如果这是您需要的数据,那么那就是处理它的方法。

但是,当您请求DISTINCT时,您需要意识到系统可能必须遍历许多记录,以确保它能够获取足够的“原始数据”以达到请求的DISTINCT值个数;最坏的情况是它必须处理所有2000万条记录! MSSQL善于利用现有数据的统计信息来猜测需要多少行。

现在,可能您的统计信息已“消失”,导致系统获取“太少”的记录,从而导致您获得了800个“快速结果”,但是却花了很多时间才能从中获取下200个(不同的值)桌子。

我建议尝试做两件事:

  • 要求一个估计的计划并学会解释它
  • 更新所述表的统计信息,然后重试,看看估计计划是否更改;尤其是估算的行数应该很有趣

祝你好运, 罗比

PS:请记住,当请求TOP n时,您将获得整个数据的“随机选择”;不能保证您将从表中获得“前” n行!要到达那里,您需要显式指定一个ORDER BY子句,可能会在查询的执行中增加(大量)额外的工作;再次,查询计划将显示此内容。 (您可以一次键入两个查询,并要求一个估计计划以查看差异。也就是说,当一个查询的成本为10%,另一个查询的成本为90%时,这并不意味着一个查询的运行速度比查询快9倍另一个,成本与时间是不一样的,尽管两者之间确实存在联系,只是不是线性的联系)