查询执行需要花费更多时间使用distinct和top子句

问题描述 投票:0回答:1

我在程序中有2个表与union all运算符相结合。第一个表包含2000万条记录,第二个表包含100万条记录。如果我单独使用Top Clause而没有distinct子句,它会给出输出,但是当我使用带有Distinct子句的TOP子句时,它会在执行该查询之后非常快地返回前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 <>''
sql-server-2008 query-optimization union-all
1个回答
1
投票

使用TOPDISTINCT没有任何问题,无论UNION ALL结构如何。如果这是您需要的数据,那么就是这样做的。

但是,当您要求使用DISTINCT时,您需要意识到系统可能需要查看大量记录以确保它获取足够的“原始数据”以获得所请求的DISTINCT值;最坏的情况是它必须超过所有2000万条记录! MSSQL非常擅长通过利用它对手头数据的统计数据来猜测它需要多少行。

现在,您的统计数据可能会“离线”,导致系统获取“太少”的记录,从而导致您获得800'快速结果',但随后需要花费大量时间从表中获取下一个200(不同的值)。

我建议尝试做两件事:

  • 询问一个估计的计划并学会解释它
  • 更新所述表的统计信息,然后再试一次,看看估计的计划是否发生变化;特别是估计的行数应该很有趣

祝你好运,罗比

PS:请记住,在要求TOP n时,您将获得整个数据的“随机选择”;无法保证您将从表中获得“第一行”n行!为了达到这个目的,你需要明确指定一个ORDER BY子句,可能会为执行查询添加(很多)额外的工作;再次,查询计划将显示此信息。 (您可以一次输入两个查询并询问估计的计划以查看差异。也就是说,当1个查询的成本为10%而另一个查询的成本为90%时,这并不意味着一个查询的运行速度比另一方面,成本与时间不一样,虽然两者之间确实存在联系,但不是线性的)

© www.soinside.com 2019 - 2024. All rights reserved.