我有一个查询,当日期条款"和datediff(day,con2.DT_DateIncluded),' 2017-01-01')< = 0"在下面的代码中没有在查询中使用,但在包含它时运行缓慢。虽然当我只运行部件时运行速度很快,但选择前2个ID_Contact ...",甚至包括date子句。我在经典ASP应用程序上有这个查询,它无法转换为存储过程(项目范围原因)。您能否通过更改查询代码帮我找到改善完整查询性能的方法?
select distinct top 10
ID_Contact, NO_CodCompany
from
tblContacts con1
where
ID_Contact in (select top 2 ID_Contact
from tblContacts con2
inner join tblCompanies cp on con2.NO_CodCompany = cp.ID_Company
where con2.NO_CodCompany = con1.NO_CodCompany
and datediff(day, con2.DT_DateIncluded), '2017-01-01') <= 0)
答案 0 :(得分:1)
这基本上是您的查询: 这是您的查询:
select distinct top 10 ID_Contact, NO_CodCompany
from tblContacts con1
where ID_Contact in (select top 2 ID_Contact
from tblContacts con2 inner join
tblCompanies cp
on con2.NO_CodCompany = cp.ID_Company
where con2.NO_CodCompany = con1.NO_CodCompany and
datediff(day, con2.DT_DateIncluded), '2017-01-01') <= 0
);
我的第一个建议是将datediff()
更改为简单的日期比较:
select distinct top 10 ID_Contact, NO_CodCompany
from tblContacts con1
where ID_Contact in (select top 2 ID_Contact
from tblContacts con2 inner join
tblCompanies cp
on con2.NO_CodCompany = cp.ID_Company
where con2.NO_CodCompany = con1.NO_CodCompany and
con2.DT_DateIncluded < '2017-01-02'
);
然后,我将删除子查询中的JOIN
。我不是100%确定这完全等同,因为这可能取决于数据中的细微差别:
select distinct top 10 ID_Contact, NO_CodCompany
from tblContacts con1
where con1.ID_Contact in (select top 2 con2.ID_Contact
from tblCompanies cp
where con1.NO_CodCompany = cp.ID_Company and
con1.DT_DateIncluded < '2017-01-02'
);
然后,如果您可以删除最外层查询中的select distinct
,则应该这样做。
答案 1 :(得分:1)
请改为尝试:
con2.DT_DateIncluded < '20170102'
它更好,因为它仍然允许服务器使用DT_DateIncluded
列上的任何索引。目前,这是不可能的。更糟糕的是,查询可能不得不在表中的每条记录上运行DATEDIFF()函数。
请注意,此 等同于您发布的内容,即使它可能与您的预期不符。我怀疑con2.DT_DateIncluded < '20170101'
更接近你的真实含义。
我还怀疑你可以在没有tblContacts的第二个实例或使用窗口函数来获得更好的结果,或者至少使用JOIN
而不是IN
来过滤结果。
最后,由于历史原因,在输入仅限日期的值时,您应该使用 unseparated 日期格式,如下所述:
对于日期/时间值,您仍然可以使用您习惯的分隔yyyy-mm-dd hh:mm:ss
,但如果您只有日期部分,则yyyymmdd
会更好。
基于此评论:
此查询的目标是从公司获取联系人,但每家公司只能使用“n”个联系人
您应该查看APPLY
运算符。遗憾的是,我仍然不清楚所有内容是如何组合在一起的,但我最少会使用APPLY
运算符来演示每个公司的两个联系人,您可以将其作为起点:
SELECT TOP 10 ct.ID_Contact, ct.NO_CodCompany
FROM tblCompanies cp
CROSS APPLY (
SELECT TOP 2 ID_Contact, NO_CodCompany
FROM tblContacs
WHERE NO_CodCompany = cp.ID_Company
AND DT_DateIncluded < '20170102'
ORDER BY DT_DateIncluded DESC
) ct
APPLY
类似于JOIN
嵌套SELECT
查询,其中没有ON
子句;相反,join条件作为嵌套WHERE
语句中SELECT
子句的一部分包含在内。
请注意CROSS
的使用。这将排除完全没有联系的公司。如果要包含这些公司,请将其更改为OUTER
。
您还应该查看已定义的索引。查看tblContacts
和NO_CodCompany
(按此顺序!)的DT_DateIncluded
表上的单个索引可能会为此查询创建奇迹,尤其是如果它在ID_Contact
中也有INCLUDES
tblContacts
条款。然后,您可以完全从索引中完成查询的int a[];
int a[2]; //OK
部分。
答案 2 :(得分:1)
而不是`DATEDIFF()&lt; 0&#39;尝试使用:
and con2.DT_DateIncluded <= '2017-01-01'
另外,确保`DT_DateIncluded&#39;上有一个索引。柱。
DATEDIFF()
运行缓慢的原因是使用它需要一些时间来执行计算,查询优化器(可能)最终为整个表运行它,并且(可能)没有索引帮助它选择所需的行。
当您删除该子句时,查询运行得更快,但这可能有助于您只选择内部查询中的前两行和外部查询中的十行,从而允许进行表扫描足够高效。