读书人

主键顺序的不同查询代价为什么不一样

发布时间: 2012-03-22 17:43:57 作者: rapoo

主键顺序的不同,查询代价为什么不一样。
对于两个表,主键相同,但是主键的顺序不同例如:
表Atest1
CREATE TABLE [develop].[Atest1] (
[YEAR_DATE_CD] [smalldatetime] NOT NULL ,
[PRICELIST_CD] [int] NOT NULL ,
[JAN] [varchar] (13) COLLATE Japanese_CI_AS NOT NULL ,
[DATE_CD] [int] NOT NULL ,
[PRODUCT_NM] [varchar] (40) COLLATE Japanese_CI_AS NOT NULL ,
[PRODUCT_SHORT_NM] [varchar] (20) COLLATE Japanese_CI_AS NOT NULL ,
[STANDARD_NM] [varchar] (20) COLLATE Japanese_CI_AS NOT NULL ,
[STANDARD_SHORT_NM] [varchar] (12) COLLATE Japanese_CI_AS NOT NULL ,
[PROD_LEVEL1_CD] [smallint] NOT NULL ,
[PROD_LEVEL2_CD] [smallint] NOT NULL ,
[PROD_LEVEL3_CD] [smallint] NOT NULL ,
[PROD_LEVEL4_CD] [smallint] NOT NULL ,
[PROD_LEVEL5_CD] [smallint] NOT NULL ,
[PROD_LEVEL6_CD] [smallint] NOT NULL ,
[PROD_LEVEL7_CD] [smallint] NOT NULL ,
[RETAIL_PRICE] [money] NOT NULL ,
[UNIT_COST_PRICE] [money] NOT NULL ,
[VENDOR_CD] [int] NOT NULL ,
[TAX_TYP] [tinyint] NOT NULL ,
[AMEND_DT] [smalldatetime] NOT NULL ,
[UPDATE_DT] [smalldatetime] NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [develop].[Atest1] ADD
CONSTRAINT [PK_Atest1] PRIMARY KEY CLUSTERED
(
[YEAR_DATE_CD],
[PRICELIST_CD],
[JAN],
[DATE_CD]
) ON [PRIMARY]
GO

表Atest2
CREATE TABLE [develop].[Atest2] (
[DATE_CD] [int] NOT NULL ,
[YEAR_DATE_CD] [smalldatetime] NOT NULL ,
[PRICELIST_CD] [int] NOT NULL ,
[JAN] [varchar] (13) COLLATE Japanese_CI_AS NOT NULL ,

[PRODUCT_NM] [varchar] (40) COLLATE Japanese_CI_AS NOT NULL ,
[PRODUCT_SHORT_NM] [varchar] (20) COLLATE Japanese_CI_AS NOT NULL ,
[STANDARD_NM] [varchar] (20) COLLATE Japanese_CI_AS NOT NULL ,
[STANDARD_SHORT_NM] [varchar] (12) COLLATE Japanese_CI_AS NOT NULL ,
[PROD_LEVEL1_CD] [smallint] NOT NULL ,
[PROD_LEVEL2_CD] [smallint] NOT NULL ,
[PROD_LEVEL3_CD] [smallint] NOT NULL ,
[PROD_LEVEL4_CD] [smallint] NOT NULL ,
[PROD_LEVEL5_CD] [smallint] NOT NULL ,
[PROD_LEVEL6_CD] [smallint] NOT NULL ,
[PROD_LEVEL7_CD] [smallint] NOT NULL ,
[RETAIL_PRICE] [money] NOT NULL ,
[UNIT_COST_PRICE] [money] NOT NULL ,
[VENDOR_CD] [int] NOT NULL ,
[TAX_TYP] [tinyint] NOT NULL ,
[AMEND_DT] [smalldatetime] NOT NULL ,


[UPDATE_DT] [smalldatetime] NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [develop].[Atest2] ADD
CONSTRAINT [PK_Atest2] PRIMARY KEY CLUSTERED
(
[DATE_CD],
[YEAR_DATE_CD],
[PRICELIST_CD],
[JAN]
) ON [PRIMARY]
GO
同时两个表里面的数据是完全相同的,都为10w条。
执行下面的语句
select
*
from
Atest2
where
date_cd=1

select
*
from
Atest1
where
date_cd=1
查询结果是相同的,但是查询代价不一样,原因?
望各位达人赐教!!!


[解决办法]


应该是第二种更快。

查看联机帮助关于簇索引的概念。


聚集索引确定表中数据的物理顺序。
聚集索引类似于电话簿,后者按姓氏排列数据。
由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。
但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。

聚集索引对于那些经常要搜索范围值的列特别有效。
使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。
例如,如果应用程序执行的一个查询经常检索某一日期范围内的记录,
则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。
这样有助于提高此类查询的性能。
同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),
避免每次查询该列时都进行排序,从而节省成本。

[解决办法]
猜测:

将把列的组合定义为PRIMARY KEY 约束时,在检索时候,虽说是由这些列的组合值来保证唯一。
但是,
这个组合的过程是不是也是按照一定顺序来的,如果这样的话,那么定义的时候得顺序就有影响了。
[解决办法]
部分索引项的查询当然于索引的次序有关

第一种情况根本不会用到索引,而是全表扫描,代价当然不同

读书人网 >SQL Server

热点推荐