性能从简单的更改到查询

时间:2015-04-09 04:53:12

标签: sql sql-server performance tsql

我曾经有一个简单的查询,按名称和日期连接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分钟才能完成。

我想知道有更有效的方法吗?

谢谢!

2 个答案:

答案 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