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

query execution taking more time with distinct and top clause

我有 2 个 table 与 union all 运算符结合,在 procedure.First table 中包含 2000 万条记录,第二个 table 包含 100 万条记录。 如果我单独使用 Top Clause 而没有 distinct 子句,它会给出输出但是当我使用带有 Distinct 子句的 TOP 子句时,它 returns 在没有 completion.is 的情况下执行该查询后非常快的前 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 <>''

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

但是,当您请求 DISTINCT 时,您需要意识到系统可能必须检查大量记录以确保它获取足够的 'raw data' 以获得请求的数字不同的值;最坏的情况是 运行 所有 2000 万条记录! MSSQL 非常擅长利用手头数据的统计数据来猜测需要多少行。

现在,您的统计数据可能 'way off' 导致系统获取 'too little' 记录,从而导致您获得了 800 'quick results' 条记录,但随后需要花费大量时间来获取接下来的 200 条记录(不同的值)来自 table.

我建议尝试做两件事:

  • 询问估计的计划并学习解释它
  • 更新所述 tables 的统计数据然后重试,看看估计的计划是否改变;特别是估计行数应该很有趣

祝你好运, 罗比

PS:请记住,当请求 TOP n 时,您将获得整个数据的 'random selection';无法保证您将从 table 中获得 'first' n 行!要到达那里,您需要明确指定一个 ORDER BY 子句,可能会为查询的执行添加(很多)额外的工作;同样,查询计划将显示这一点。 (您可以同时输入这两个查询并询问估计的计划以查看差异。也就是说,当一个查询的成本为 10% 而另一个为 90% 时,这并不意味着一个将 运行比另一个快9倍,成本与时间不一样,虽然两者之间确实存在link,只是不是线性的)