关于索引的奇怪问题,请指教,谢谢!

BigAngell 2010-10-19 12:39:47
两张表:
df_cbk有字段id和dbbh,id是主键,dbbh是索引;
sg186_df_cbk有字段id和dbbh,id是主键;

df_cbk与sg186_df_cbk的关联字段是id,数据大概在10万条左右。

sg186_df_cbk是中间(临时用到),数据定写入sg186_df_cbk后,要转存到df_cbk,大家都知道update的速度是很慢的,所以的处理方法是删除df_cbk已存于sg186_df_cbk中的数据,再将sg186_df_cbk的数据全部写入df_cbk,这样速度应该更快点。

现在的问题是:
当我用id关联删除df_cbk时,花费了很久时间都没成功(十几分钟),结果发现没有用到任何索引,然后改用select count(*)也是如此,具体SQL如下:
一、id关联(十几分钟后仍没有结果)
SELECT count(*)
FROM df_cbk, sg186_df_cbk cbk
WHERE df_cbk.id = cbk.id

但后来我测试发现用dbbh关联反而速度很快(几秒),SQL如下:
二、dbbh关联(2秒钟不到就出结果)
SELECT count(*)
FROM df_cbk, sg186_df_cbk cbk
WHERE df_cbk.dbbh = cbk.dbcode
但dbbh不能作为可靠的关联条,因为dbbh不唯一。

请大家帮我解答这是为什么?怎么解决?
...全文
102 点赞 收藏 12
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
zsh0809 2010-10-19
选中你的SQL,按CTRL + L 查看执行计划,看看有没有用到Index SCAN,
如果是table Scan则必须建立相应的Index。
回复
SQLCenter 2010-10-19
Ctrl+L 这句有没有走索引
select * from df_cbk t where exists (select id from sg186_df_cbk where id=t.id)
回复
SQL77 2010-10-19
[Quote=引用 11 楼 bigangell 的回复:]
问题解决了,谢谢大家热心解答!

很奇怪,跟字段类型有关,df_cbk.id是MONEY型的,sg186_df_cbk.id是NUMERIC(16)的,类型相同就对了!
[/Quote]
额,类型不同肯定会向优先级高的转换
回复
BigAngell 2010-10-19
问题解决了,谢谢大家热心解答!

很奇怪,跟字段类型有关,df_cbk.id是MONEY型的,sg186_df_cbk.id是NUMERIC(16)的,类型相同就对了!
回复
SQL77 2010-10-19
Index : PK_df_cbk Forward scan.
Positioning at index start.
Index contains all needed columns. Base table will not be read.
Using I/O Size 16 Kbytes for index leaf pages.
With LRU Buffer Replacement Strategy for index leaf pages.

FROM TABLE
sg186_df_cbk
cbk
Nested iteration.
Index : PK_sg186_df_cbk Forward scan.
Positioning at index start
回复
SQLCenter 2010-10-19
整理一下df_cbk的索引试试
DBCC INDEXDEFRAG ('database_name', 'df_cbk')
回复
zsh0809 2010-10-19
是主键,那内连接的时候为什么没走到索引呢?

  SELECT count(*)
FROM df_cbk, sg186_df_cbk cbk
WHERE df_cbk.id = cbk.id

你这句SQL 的执行计划中有table scan?
回复
BigAngell 2010-10-19
[Quote=引用 5 楼 zsh0809 的回复:]

引用 3 楼 bigangell 的回复:

引用 1 楼 sqlcenter 的回复:

Ctrl+L 这句有没有走索引
SQL code
select * from df_cbk t where exists (select id from sg186_df_cbk where id=t.id)


没有用到索引

那就先给相关栏位加上索引。
[/Quote]

id是主键,难道还要为它建索引,好像建不起的。
回复
BigAngell 2010-10-19
错了,这个才是用id关联的执行计划内容:

QUERY PLAN FOR STATEMENT 1 (at line 1).


STEP 1
The type of query is SELECT.
Evaluate Ungrouped COUNT AGGREGATE.

FROM TABLE
df_cbk
Nested iteration.
Index : PK_df_cbk
Forward scan.
Positioning at index start.
Index contains all needed columns. Base table will not be read.
Using I/O Size 16 Kbytes for index leaf pages.
With LRU Buffer Replacement Strategy for index leaf pages.

FROM TABLE
sg186_df_cbk
cbk
Nested iteration.
Index : PK_sg186_df_cbk
Forward scan.
Positioning at index start.
回复
zsh0809 2010-10-19
[Quote=引用 3 楼 bigangell 的回复:]

引用 1 楼 sqlcenter 的回复:

Ctrl+L 这句有没有走索引
SQL code
select * from df_cbk t where exists (select id from sg186_df_cbk where id=t.id)


没有用到索引
[/Quote]
那就先给相关栏位加上索引。
回复
BigAngell 2010-10-19
这个是执行计划的内容:
STEP 1
The type of query is SELECT.
Evaluate Ungrouped COUNT AGGREGATE.

FROM TABLE
sg186_df_cbk
cbk
Nested iteration.
Table Scan.
Forward scan.
Positioning at start of table.
Using I/O Size 16 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.

FROM TABLE
df_cbk
Nested iteration.
Index : idx_df_cbk_dbbh
Forward scan.
Positioning by key.
Index contains all needed columns. Base table will not be read.
Keys are:
dbbh ASC
Using I/O Size 8 Kbytes for index leaf pages.
With LRU Buffer Replacement Strategy for index leaf pages.

STEP 2
The type of query is SELECT.
回复
BigAngell 2010-10-19
[Quote=引用 1 楼 sqlcenter 的回复:]

Ctrl+L 这句有没有走索引
SQL code
select * from df_cbk t where exists (select id from sg186_df_cbk where id=t.id)
[/Quote]

没有用到索引
回复
相关推荐
发帖
疑难问题
创建于2007-09-28

2.1w+

社区成员

MS-SQL Server 疑难问题
申请成为版主
帖子事件
创建了帖子
2010-10-19 12:39
社区公告
暂无公告