首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

主键顺序的不同,查询代价为什么不一样。解决方法

2012-03-22 
主键顺序的不同,查询代价为什么不一样。对于两个表,主键相同,但是主键的顺序不同例如:表Atest1CREATETABLE[

主键顺序的不同,查询代价为什么不一样。
对于两个表,主键相同,但是主键的顺序不同例如:
表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 约束时,在检索时候,虽说是由这些列的组合值来保证唯一。
但是,
这个组合的过程是不是也是按照一定顺序来的,如果这样的话,那么定义的时候得顺序就有影响了。
[解决办法]
部分索引项的查询当然于索引的次序有关

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

热点排行