优化sqlado返回时间

优化sqlado返回时间,sql,sql-server,excel,ado,vba,Sql,Sql Server,Excel,Ado,Vba,我尝试了以下查询,以使用ADO将结果集返回excel MAX SELECT DISTINCT Term FROM uSubjectivities WHERE account_no = '1172014' AND version_num = (SELECT max(Cast(version_num as Int)) from uSubjectivities WHERE account_no='1172014'

我尝试了以下查询,以使用ADO将结果集返回excel

MAX

SELECT DISTINCT Term
FROM uSubjectivities 
WHERE account_no = '1172014'
    AND version_num = (SELECT max(Cast(version_num as Int)) from uSubjectivities 
                            WHERE account_no='1172014' 
                                AND SubjectivityID = '6472140') 
        AND SubjectivityID = '6472140'
        AND TermType = 'Common'
顶部(1)

更新 加入

SELECT DISTINCT Term
FROM uSubjectivities S
INNER JOIN 
(
    SELECT TOP (1) Cast(version_num as Int) v
    FROM uSubjectivities 
    WHERE account_no='1172014' 
        And SubjectivityID = '6472140'
    ORDER BY version_num DESC
) mv
ON mv.v = s.version_num
WHERE SubjectivityID = '6472140'
    AND TermType = 'Common'
然而,这两项都比我(和我的用户)想要的时间长得多

Max需要14秒才能返回15条记录(类型为varchar(Max),因为它们可以是具有长文本字符串的字段)。第一名需要14秒。加入需要16秒

单引号内的任何参数最终都会传递到查询中。我运行查询大约6次(但可能或多或少取决于参数)。在我现在的示例中,这部分代码在Max上花费42秒,在Top 1上花费37秒。40秒加入

是否有任何方法可以优化此速度。目前,我们正试图避免索引,因为数据库将不得不一次又一次地重新编制索引

此外,这两个查询都在SQLServer中以纳秒的速度运行,所以我不知道为什么它们在ADO中运行得这么慢

编辑
我还将其加载到一个存储过程中,并从VBA中调用。对返回时间没有帮助。

您遇到了一个名为关联子查询的问题:

在SQL数据库查询中,相关子查询(也称为 同步子查询)是一个子查询(嵌套在另一个子查询中的查询) 查询)使用外部查询中的值。因为子查询可能 对于外部查询处理的每一行计算一次,可以 效率低下

请参见另一个示例:

 SELECT employee_number, name
   FROM employees AS emp
   WHERE salary > (
     SELECT AVG(salary)
       FROM employees
       WHERE department = emp.department);

要解决此问题,您必须加入结果,而不是在第一个选择中执行另一个选择,选中此答案您可以尝试取消子查询,并在主选择中使用order by with top:

SELECT TOP 1 Term
FROM uSubjectivities 
WHERE account_no = '1172014'
AND SubjectivityID = '6472140'
AND TermType = 'Common'
ORDER BY version_num desc
下面是n行的另一个选项:


也许将查询存储在SS中会加快处理速度,因为作为存储的SS对象,它们会得到优化—只需根据需要传入参数即可。此外,请确保您是检索数据的“最佳”驱动程序。如果可能,使用本机SQL SERVER驱动程序而不是通用ODBC驱动程序。哦,是的,还有一件事。。。关于纳秒会导致SS。。。在MGMT STUDIO中确保“完整”结果集已在纳秒内返回。很有可能您的结果窗口,即使它看起来像您有您的结果,可能仍然在填充。@flaZer-您是说将过程存储在SQLServer本身中,然后用参数从ADO调用它?(另外,我正在使用本机SQLServer驱动程序并获得完整的结果集)。@DMason-感谢您的评论。我在这里学习,你说的比我同事说的更有意义:)我也想到了这一点,但我需要返回每个最新版本号的n行。@ScottHoltzman忽略了这一点,添加了另一种方法。。顺便说一句,ADO的表现似乎很糟糕,因为您的查询方式很好。也许它能更好地处理
RANK()
,但这可能是一个充满希望的想法。我现在正在尝试排名。不幸的是,它的表现比所有选项都差,所有呼叫的总时间为46秒。@ScottHoltzman哈,糟糕透了。很抱歉周围一定有熟悉这件事的人。我注意到的另一件事是,在原始查询中,
TermType='Common'
不在子查询过滤器中。您最好将它放在子查询的内部和外部,就像其他过滤器一样。我非常怀疑这会解决这个问题,值得注意的是,我的子查询可以独立运行,并且独立于外部查询。我现在正在测试join out,看看它是否有用。将其作为join编写会使总运行时间增加3秒:(我可以看到使用join编写的查询吗?
SELECT TOP 1 Term
FROM uSubjectivities 
WHERE account_no = '1172014'
AND SubjectivityID = '6472140'
AND TermType = 'Common'
ORDER BY version_num desc
SELECT Term
FROM (SELECT Term,
             RANK() over (ORDER BY version_num desc) AS RK
      FROM uSubjectivities 
      WHERE account_no = '1172014'
      AND SubjectivityID = '6472140'
      AND TermType = 'Common') A
WHERE RK = 1