2011-04-06 66 views
4

使用SQL Server 2005,在以下情况下加入两个表的最有效方法是什么?SQL Server 2005 - 根据表列中的条件进行连接

每个表格中的记录数量可能相当大,约为200000个。

我现在唯一想到这样做的唯一方法是对每个项目使用游标和一些动态SQL,这显然会非常低效。

我有两个表 - PERSON表和SEARCHITEMS表。 SEARCHITEMS表包含一个列,其中包含一些简单条件,将表与PERSON表匹配时将使用该列。该条件可引用PERSON表中的任何列。

例如给出如下表:

PERSON

PERSONID FIRSTNAME LASTNAME GENDER AGE ... VARIOUS OTHER COLUMNS 
1   Fred  Bloggs M  16 
.... 
200000  Steve  Smith M  18 

SEARCHITEMS

ITEMID   DESCRIPTION  SEARCHCRITERIA 
1    Males   GENDER = 'M' 
2    Aged 16   AGE=16 
3    Some Statistic {OTHERCOLUMN >= SOMEVALUE AND OTHERCOLUMN < SOMEVALUE} 
.... 
200000   Males Aged 16 GENDER = 'M' AND AGE = 16 

RESULTS表应包含这样的事情:

ITEMID   DESCRIPTION  PERSONID LASTNAME 

1    Males    1   Bloggs 
1    Males    200000  Smith 
2    Aged 16   1   Bloggs 
.... 
200000   Males Aged 16  1   Bloggs 

这将是很好能够只是像做

INSERT INTO RESULTSTABLE 
    SELECT * 
    FROM PERSON P 
    LEFT JOIN SEARCHITEMS SI ON (APPLY SI.SEARCHCRITERIA TO P) 

,但我看不到使这项工作的一种方式。任何帮助或想法表示赞赏。

+0

你试图完全解决什么问题?仅仅是加入这两张表的要求? – Ali 2011-04-06 10:50:32

+0

要求是将任何匹配记录的结果插入到结果表中 - 它不一定需要使用它只需要有效的连接 - 如果可以实现,我发现连接最终效率最高。 – 2011-04-06 11:09:21

+0

我认为我们应该在人员和搜索项目之间建立一个中间表格,因为结果表格的大小与当前描述的大小不符,我曾考虑过这个问题,除非您知道所有搜索条件组合(我非常怀疑),否则我无法想出使用游标的更好解决方案。 – Ali 2011-04-06 11:21:16

回答

-1

您可以动态构建您的TSQL,然后使用sp_executesql执行它。

5

看到SEARCHITEMS表本质上是非关系型的,似乎光标和动态SQL解决方案是唯一可行的解​​决方案。当然这会很慢,我会“预先计算”结果,使它有点可以承受。

为此创建下表:

CREATE TABLE MATCHEDITEMS(
    ITEMID int NOT NULL 
     CONSTRAINT fkMatchedSearchItem 
     FOREIGN KEY 
     REFERENCES SEARCHITEMS(ITEMID), 
    PERSONID int 
     CONSTRAINT fkMatchedPerson 
     FOREIGN KEY 
     REFERENCES PERSON(PERSONID) 
     CONSTRAINT pkMatchedItems 
     PRIMARY KEY (ITEMID, PERSONID) 
     ) 

该表将包含大量的数据,但考虑到它只能存储2分INT列在磁盘上占用空间会很小。

要更新此表创建以下触发器:

  • 在SEARCHITEMS表每当一个规则被改变或增加,这将填充MATCHEDITEMS表的触发器。
  • PERSON表上的触发器,它将运行更新或添加的PERSON记录上的规则。

结果可以简单地通过加入3个表格来呈现。

SELECT m.ITEMID, m.DESCRIPTION, m.PERSONID, p.LASTNAME 
FROM MATCHEDITEMS m 
JOIN PERSON p 
    ON m.PERSONID = p.PERSONID 
JOIN SEARCHITEMS s 
    ON m.ITEMID = s.ITEMID 
+0

+ +1提出了一个明智的解决方法。我不认为有更好的解决方案,并且至少在初始加载完成后,这些内容会随触发器一起更新。 – 2011-04-06 11:29:33

+0

感谢您花时间回答此问题。我没有想过使用触发器来更新表的想法。 – 2011-04-06 13:11:08