选择效率更高

时间:2013-03-13 08:52:35

标签: sql sql-server sql-server-2008

在SQL Server 2008中,我有一个表,其中包含来自我们网站的下载活动的数据。我已经创建了一个工具来手动匹配Web下载表中的每个公司到我们客户数据库中的帐户。并非所有下载者都属于客户公司。这些非客户与默认帐户匹配。

下载表中的公司名称可能以多种不同的方式拼写,因此许多不同的名称与同一帐户匹配。

公司可能存在于不同的国家。每个公司都有自己的客户数据库中每个国家/地区的帐户,但只有一个默认帐户(每个国家/地区不是一个)。为了使这更加复杂,下载者不需要指定国家(无关)。在这些情况下,匹配是最可能的帐户。在这些情况下,country字段将包含一个空格。到目前为止,非常好。

当我想从webDownloadTable列出那些与现有帐户(或默认帐户)不匹配的公司时,问题就出现了,即:在accountMatchingTable中不存在。

webDownloadTable中最重要的列是:

webDownloadTable(
ID int not null
webCompanyName varchar(200), 
webCountryName varchar(200), 
item integer(8),
......,
...
);

主键是ID

匹配表如下所示:

accountMatchingTable(
AccountID int(8),
matchedCompanyName varchar(200),
matchedCountryName varchar(200),
......,
...
);

主键是(AccountID, matchedCompanyName, matchedCountryName)

这些表格似乎以良好的方式编制索引。

我做了一个实际可行的SQL选择,但随着行数的增加,它将变得非常慢。它选择了公司名称+国家/地区不匹配的前15行:

SELECT  DISTINCT TOP 15 webCompanyName, webCountryName
FROM    webDownloadTable
WHERE   (webCompanyName + webCountryName NOT IN
        (SELECT matchedCompanyName + matchedCountryName FROM accountMatchingTable)  /*The combination of name and country from the matching table*/
)
    AND
    (webCompanyName + ' ' NOT IN
        (SELECT matchedCompanyName + matchedCountryName FROM accountMatchingTable)  /*The combination of name and an empty space from the matching table (see §. below)*/
    )
ORDER BY webCompanyName, webCountryName;

§。需要此部分来选择国家/地区开放的情况(参见上面的解释)。

有没有人可以帮我创建更高效​​的选择?

3 个答案:

答案 0 :(得分:3)

如何删除这两个子查询:

SELECT  DISTINCT TOP 15 a.webCompanyName, a.webCountryName
FROM    webDownloadTable a
  LEFT OUTER JOIN accountMatchingTable b
    ON a.webCompanyName + a.webCountryName = b.webCompanyName + b.webCountryName
    OR a.webCompanyName + ' ' = b.webCompanyName + b.webCountryName
WHERE b.webCompanyName IS NULL
ORDER BY webCompanyName, webCountryName

答案 1 :(得分:1)

我认为这会解决问题:

SELECT DISTINCT TOP 15 webCompanyName,
                       webCountryName
FROM   webDownloadTable
       LEFT OUTER JOIN accountMatchingTable
         ON webDownloadTable.webCompanyName = accountMatchingTable.matchedCompanyName
            AND (webDownloadTable.webCountryName = accountMatchingTable.matchedCountryName
                  OR accountMatchingTable.matchedCountryName = ' ')
WHERE  accountMatchingTable.matchedCompanyName IS NULL
ORDER  BY webCompanyName,
          webCountryName;

我不相信DISTINCT TOP 15 - 最好在子查询中执行distinct,然后从中选择TOP 15,或者使用由两个值分区的排名函数。

答案 2 :(得分:1)

您可以尝试使用NOT EXISTS子句,如下所示:

SELECT  DISTINCT TOP 15 webCompanyName, webCountryName
FROM    webDownloadTable d
WHERE NOT EXISTS
(SELECT 1
 FROM accountMatchingTable m
 WHERE m.matchedCompanyName = d.webCompanyName AND
       m.matchedCountryName in (d.webCountryName, ' ')
)
ORDER BY webCompanyName, webCountryName;

通过单独加入公司名称和国家/地区名称​​(而不是单个串联字符串),应该可以使用任何合适的现有索引。