SQL Server索引问题 - 地址查找

时间:2009-04-10 19:11:58

标签: sql sql-server

我有一个表,在应用程序的生命周期中可能有10,000到1000万行。此表包含NACSZ信息,以及其他内容,我需要编写一个查询匹配NACSZ的查询,如下所示:

select 
    * 
from 
    Profiles 
where 
    FirstName = 'chris' and
    LastName = 'test' and
    Address1 = '123 main st' and
    City = 'chicago' and
    State = 'il' and
    Zip = '11111'

我正在尝试优化此查询的表,该表将在“if exists()”构造内运行,并且没有太多运气。没有索引,大约110,000行测试数据,我得到:

  

表'个人资料'。扫描计数1,   逻辑读取2021,物理读取0,   预读读取0,lob逻辑读取   0,lob物理读取0,lob   预读读取0。

     

(1行受影响)

     

SQL Server执行时间:CPU   时间= 16毫秒,经过时间= 70毫秒。

     

SQL Server执行时间:CPU   时间= 0毫秒,经过时间= 1毫秒。

执行计划表示主键上的聚簇索引扫描。我想为所有值添加一个索引,但这会产生一个相当大的键,我想尽可能避免这种情况。我的下一个想法是索引行之间会有相当不同的东西,所以我尝试在名字上编制索引(虽然我可以使用地址行1或zip,例如),所以我创建了索引:

create index ix_profiles_firstName on profiles(FirstName)

现在,当我运行相同的查询时,我得到了

  

表'个人资料'。扫描计数1,   逻辑读取171,物理读取0,   预读读取0,lob逻辑读取   0,lob物理读取0,lob   预读读取0。

     

(1行受影响)

     

SQL Server执行时间:CPU   时间= 0毫秒,经过时间= 52毫秒。

     

SQL Server执行时间:CPU   时间= 0毫秒,经过时间= 1毫秒。

显然,索引名字会产生巨大的差异。我的问题是,我如何决定是否应该将名字与姓氏和地址与邮政编码进行索引?是否有一个命令可以运行我的样本数据,它会告诉我每个字段中值的唯一性?我的理解是,我应该尝试使用最独特的索引对列进行索引以使索引最佳,正确吗?

5 个答案:

答案 0 :(得分:3)

对于您的查询,您应该在所有列上创建复合索引:(FirstName, LastName, address1, city, state, zip)

如果您希望在SQL Server中使用某个索引,请发出:

SELECT  *
FROM    Profiles WITH (INDEX (index_name))
WHERE 
        FirstName = 'chris' and
        LastName = 'test' and
        Address1 = '123 main st' and
        City = 'chicago' and
        State = 'il' and
        Zip = '11111'
  

我的问题是,我该如何决定是否应该将名字与姓氏对地址与邮政编码进行索引?

索引您要过滤的所有这些值。

请注意,您可以有效地过滤索引中的第一列,例如:

SELECT  *
FROM    Profiles
WHERE   FirstName = 'chris'

将使用索引搜索FirstName

SELECT  *
FROM    Profiles
WHERE   FirstName = 'chris'
        AND LastName = 'test'

将使用索引搜索FirstNameLastName

SELECT  *
FROM    Profiles
WHERE   FirstName = 'chris'
        AND City = 'chicago'

将使用索引仅在FirstName上搜索(您不在LastName上过滤,存在差距,并且索引不能用于搜索其他列)

  

是否有一个命令可以运行我的示例数据,它会告诉我每个字段中值的唯一性?

SELECT   COUNT(DISTINCT FirstName) / COUNT(*)
FROM     Profiles

将显示FirstName互惠选择性。

此值越大,索引的效率就越低。

  

我的理解是,我应该尝试使用最独特的列索引索引以使索引最佳,正确吗?

同样,在您的情况下,您应该索引所有列。在所有专栏中,最独特的是肯定的。

答案 1 :(得分:1)

  

我的问题是,我该如何决定是否应该将名字与姓氏对地址与邮政编码进行索引?

收集您打算使用的所有查询(如果这是唯一的,您就完成了)。然后将查询作为工作负载转交给索引优化向导,并查看建议。

  

我的理解是,我应该尝试使用最独特的列索引索引以使索引最佳,正确吗?

索引越独特,从实际表中查找的结果就越少。 索引越窄,读取的速度就越快。 (此规则说明了为什么所有条件列上的复合索引都不好)。

答案 2 :(得分:1)

如果此查询看起来很重要,那么我建议您在字段上创建一个派生列作为连接;然后在您的查询中显式创建密钥。当然它是多余的,但如果你不需要它,它可能最终会比把它弄得乱七八糟。

答案 3 :(得分:1)

你有几个选择。正如Quassnoi所说,你可以创建一个复合索引。我在略有不同的情景中使用的另一个选项是根据数据生成唯一键。在我的情况下,我正在比较地址并试图防止重复(因为我们会对任何新地址进行地理编码,每个地理编码成本为$$)。

无论如何,基本上我们接收了地址的关键部分并创建了一个新密钥(Address,State& Zip)。你可以做同样的事情,然后只对一列进行比较。

一个gottcha确保在记录更改时同步此列。您可以查看使用计算列和索引可能有助于此效果的索引。

答案 4 :(得分:0)

除了其他答案......

您将运行哪种过滤器组合?尝试覆盖最流行的组合。