表分区后不走索引?

ojekleen 2011-08-11 01:28:35
查询语句

select id,[收货人名称] ,[申报日期] ,[商品编码] ,[价格] FROM dbo.dc_Russia WHERE [申报日期] between '2010-1-1 0:00:00' and '2011-8-11 0:00:00' and [商品编码]='9026'

索引创建是

CREATE NONCLUSTERED INDEX [index_hs_date] ON [dbo].[dc_Russia]
(
[商品编码] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [Data_Partition_Scheme]([申报日期])

[Data_Partition_Scheme]([申报日期])是表分区方案

执行计划却是要表扫描,为什么呢?
...全文
573 35 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
bapi 2011-08-13
  • 打赏
  • 举报
回复
数据分布:
3 2010-01-01 00:00:00.000 2010-12-31 00:00:00.000 15572590
4 2011-01-01 00:00:00.000 2011-04-30 00:00:00.000 6297876

查询条件:
between '2010-1-1 0:00:00' and '2011-8-11 0:00:00'

从上面分析来看,你的查询条件中时间跨度太大,根据[申报日期]上的索引,预计命中的记录数占到全表数据量的90%左右,所以优化器不太可能选中这个索引。
分区方案和索引再合理,也架不住海量数据检索啊,就你上面提供的情况来看,得要缩小查询条件中的时间跨度才能有效提高效率。
yuanwza 2011-08-12
  • 打赏
  • 举报
回复
学习.....
ojekleen 2011-08-11
  • 打赏
  • 举报
回复
第一步:先在时间列上建聚集索引
第二步:建索引CREATE NONCLUSTERED INDEX [idx_colombia_hs] ON [dbo].[dc_Colombia] ([申报日期], [商品编码])INCLUDE( id,[收货人名称] ,[价格] )
好半天才完,现在我更郁闷了,不行啊,执行计划中聚集索引运算符开销要600+...
nzperfect 2011-08-11
  • 打赏
  • 举报
回复
CREATE NONCLUSTERED INDEX [idx_colombia_hs] ON [dbo].[dc_Colombia] ([申报日期], [商品编码])INCLUDE( id,[收货人名称] ,[价格] )
oO寒枫Oo 2011-08-11
  • 打赏
  • 举报
回复
试试 在大表上面加个索引 估计要等的时间够呛 呵呵
ojekleen 2011-08-11
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 perfectaction 的回复:]
针对:
select id,[收货人名称] ,[申报日期] ,[商品编码] ,[价格] FROM dbo.dc_Russia WHERE [申报日期] between '2010-1-1 0:00:00' and '2011-8-11 0:00:00' and [商品编码]='9026'

这句:
最好的索引是:
[申报日期], [商品编码] include( id,[收货人名称] ,……
[/Quote]
可以详细点不?我SQL的代码能力比较差。。。不好意思啊
nzperfect 2011-08-11
  • 打赏
  • 举报
回复
针对:
select id,[收货人名称] ,[申报日期] ,[商品编码] ,[价格] FROM dbo.dc_Russia WHERE [申报日期] between '2010-1-1 0:00:00' and '2011-8-11 0:00:00' and [商品编码]='9026'

这句:
最好的索引是:
[申报日期], [商品编码] include( id,[收货人名称] ,[价格] )
你可以试试有没有效果再说.
ojekleen 2011-08-11
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 perfectaction 的回复:]
其实你建一个这两个字段的复合索引就应该能解决你的问题
[申报日期] , [商品编码]
[/Quote]
这个我应该建了的,

CREATE NONCLUSTERED INDEX [idx_colombia_hs] ON [dbo].[dc_Colombia]
(
[NANDINA ] ASC,
[Date Declaration ] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]

这个是我哥伦比亚表的索引创建语句,有建,聚集索引在时间列上,但是执行这个语句,聚集索引消耗很大,
ojekleen 2011-08-11
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 nbdba 的回复:]
RID查找消耗多,使因为你没有聚集索引

这个也可以用include索引解决


SQL code

CREATE NONCLUSTERED INDEX [index_hs_date] ON [dbo].[dc_Russia]
(
[商品编码] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_D……
[/Quote]

你说的没错,因为这个表大,刚才发现没有聚集索引,我有个小表,一样的情况,建了聚集索引,但是聚集索引开耗很大,和RID一样的值,所以我才郁闷
ojekleen 2011-08-11
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 lxpbs8851 的回复:]
SQL code


select id,[收货人名称] ,[申报日期] ,[商品编码] ,[价格]
FROM dbo.dc_Russia(index [index_hs_date] )
WHERE [申报日期] between '2010-1-1 0:00:00' and '2011-8-11 0:00:00' and [商品编码]='9026'


看这样走不走
[/Quote]

这个试过了,不走。with(index=index_hs_date)
nzperfect 2011-08-11
  • 打赏
  • 举报
回复
其实你建一个这两个字段的复合索引就应该能解决你的问题
[申报日期] , [商品编码]
NBDBA 2011-08-11
  • 打赏
  • 举报
回复
RID查找消耗多,使因为你没有聚集索引

这个也可以用include索引解决

CREATE NONCLUSTERED INDEX [index_hs_date] ON [dbo].[dc_Russia] 
(
[商品编码] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [Data_Partition_Scheme]([申报日期])
INCLUDE (id,[收货人名称] ,[申报日期] ,[商品编码] ,[价格] )


ojekleen 2011-08-11
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 nbdba 的回复:]
分区数据要尽量平均


5 2431-04-09 00:00:00.000 9008-09-01 00:00:00.000 191
这也有数据,呵呵

我觉得如果不进行切换分区,按时间分区很难合理,你的应用,不能按[商品编码]做合理分区吗?
[/Quote]
数量有可能会有些错误,呵呵,但不会太多。
ojekleen 2011-08-11
  • 打赏
  • 举报
回复
第一张是:
select count(*) FROM dbo.dc_Russia WHERE [申报日期] between '2010-1-1 0:00:00' and '2011-8-11 0:00:00' and [商品编码]='9026'

第二第三张是:
select id,[收货人名称] ,[申报日期] ,[商品编码] ,[价格] FROM dbo.dc_Russia WHERE [申报日期] between '2010-1-1 0:00:00' and '2011-8-11 0:00:00' and [商品编码]='9026'
ojekleen 2011-08-11
  • 打赏
  • 举报
回复
执行计划的几张图:


NBDBA 2011-08-11
  • 打赏
  • 举报
回复
分区数据要尽量平均


5 2431-04-09 00:00:00.000 9008-09-01 00:00:00.000 191
这也有数据,呵呵

我觉得如果不进行切换分区,按时间分区很难合理,你的应用,不能按[商品编码]做合理分区吗?
oO寒枫Oo 2011-08-11
  • 打赏
  • 举报
回复

select id,[收货人名称] ,[申报日期] ,[商品编码] ,[价格]
FROM dbo.dc_Russia(index [index_hs_date] )
WHERE [申报日期] between '2010-1-1 0:00:00' and '2011-8-11 0:00:00' and [商品编码]='9026'

看这样走不走
ojekleen 2011-08-11
  • 打赏
  • 举报
回复
分区号 最小日期 最大日期 行数
1 2008-01-01 00:00:00.000 2008-12-04 00:00:00.000 39812
2 2009-01-02 00:00:00.000 2009-12-28 00:00:00.000 2465280
3 2010-01-01 00:00:00.000 2010-12-31 00:00:00.000 15572590
4 2011-01-01 00:00:00.000 2011-04-30 00:00:00.000 6297876
5 2431-04-09 00:00:00.000 9008-09-01 00:00:00.000 191

上面的是全表行数。加起来不超过3000W
between '2010-1-1 0:00:00' and '2010-12-31 0:00:00' and [商品编码]='9026'
总共59804行
ojekleen 2011-08-11
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 perfectaction 的回复:]
count(*)可以直接走索引,select 字段有可能通过聚集键再去关联,成本可能比全表扫更高,提供下
'2010-1-1 0:00:00' and '2011-8-11 0:00:00' 有多少数据
[申报日期] between '2010-1-1 0:00:00' and '2011-8-11 0:00:00' and [商品编码]='9026'有多少数据
[/Quote]
哥,你这讲到点子上了,我刚仔细看了下计划,[商品编码]='9026'这个索引是走了的,
[申报日期] between '2010-1-1 0:00:00' and '2011-8-11 0:00:00' 原表扫描是这个,我晕啊
数据我马上提供
nzperfect 2011-08-11
  • 打赏
  • 举报
回复
count(*)可以直接走索引,select 字段有可能通过聚集键再去关联,成本可能比全表扫更高,提供下
'2010-1-1 0:00:00' and '2011-8-11 0:00:00' 有多少数据
[申报日期] between '2010-1-1 0:00:00' and '2011-8-11 0:00:00' and [商品编码]='9026'有多少数据
加载更多回复(15)

34,838

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧