我曾经有一个简单的查询,按名称和日期连接2个表。
表A:
Name Date Field1 Field2 Field3 ....
Abc 05-Apr-15 ... ... ... ...
表B:
Name Date Field1 Field2 ....
Abc 01-Apr-15 ... ... ...
查询:
select a.*, b.*
from tableA a
outer apply
(select top 1 *
from tableB b
where b.name = a.name
and b.date < a.date) x
此查询大约需要1秒才能运行。
由于2个表中的名称字段存在差异,因此我创建了一个参考表来标准化名称。所以我构建了如下的查询:
select a.*, b.*
from tableA a
left join refFile ref
on a.name = ref.aName
outer apply
(select top 1 *
from tableB b
left join refFile ref
on b.name = ref.bName
where isnull(ref.stdName, b.name) = isnull(ref.stdName, a.name)
and b.date < a.date) x
现在这个新查询大约需要5分钟才能完成。
我想知道有更有效的方法吗?
谢谢!
答案 0 :(得分:2)
如果没有其他人提到的执行计划,很难说但是在这里试试这个:
select a.*, b.*
from tableA a
left join refFile ref
on a.name = ref.aName
outer apply
(select top 1 *
from tableB b
left join refFile ref
on b.name = ref.bName
--It's not recommended to use functions in the where clause
--because it wont use your indexes
--where isnull(ref.stdName, b.name) = isnull(ref.stdName, a.name)
--try this instead.
WHERE (ref.stdName IS NULL AND A.Name = B.name)
OR (ref.stdName IS NOT NULL)
AND b.date < a.date) x
另外,为什么没有ORDER BY的TOP?建议将它们一起使用以确保一致的结果。
答案 1 :(得分:0)
我假设你的refFile
表看起来像这样:
create table refFile
( stdName varchar primary key
, aName varchar
, bName varchar
)
第1部分。看起来不错
select a.*, b.*
from tableA a
left join refFile ref on a.name = ref.aName
第2部分。你再次加入refFile
,为什么?除了b.date < a.date
之外,与查询的第1部分没有任何关系。除此之外,该部分之外没有表b
,这意味着第1部分中的b.*
无法正常工作。
outer apply (
select top 1 *
from tableB b
left join refFile ref
on b.name = ref.bName
where isnull(ref.stdName, b.name) = isnull(ref.stdName, a.name)
and b.date < a.date) x
建议第2部分:
outer apply (
select top 1 b.*
from tableB b
where B.name in (ref.bName, ref.stdName)
and b.date < a.date
order by b.date desc
) b