设定主键类型问题,欢迎讨论!

sqn1982 2009-04-29 08:27:05
我们在设计数据库字段的时候,将主键设为uniqueidentifier类型,这样主键就永远不会重复。在MS-SQL2005中将uniqueidentifier类型的主键设为聚集索引(默认的主键就为聚集索引),此表数据量已为百万级,并且更新频率非常高,这样做合理吗?
...全文
237 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
ks_reny 2009-04-29
  • 打赏
  • 举报
回复
用ID做主鍵.
hery2002 2009-04-29
  • 打赏
  • 举报
回复
通常情况下,在建立索引时有如下一些技巧:
(1)根据数据量的大小来确定是否建立索引。
数据表中的数据量的大小将决定是否建立索引,是否建立多个索引。对于数据量较小或者数据列较少的表,建立了主键后,不需要建立额外的索引。如果建立了索引,查询分析器在分析时,需要首先扫描索引,然后才会建立执行计划,这样会增加额外的时间来处理这个过程。对于小数据量的表来说,这个过程是不必要的。因为小数据量的表简单扫描的响应时间可能比查询分析器通过索引优化的时间要短。对于数据量较大或者数据列较多的表,可以建立一个或者多个索引来优化查询。
(2)根据数据更新的频率来确定是否建立索引。
数据的更新会同时维护索引,如果在频繁修改的数据列上建立索引,则系统会额外地维护索引,从而增加数据更新的时间。所以,应该避免在数据频繁更新的数据列上建立索引。
(3)根据索引的使用频率来确定是否分开存储和访问。
将使用频繁的索引和其它索引分开来存储,将频繁访问的索引文件存放在读写性能好的磁盘或者磁盘阵列上,以获得物理布局上的性能提升,从而加快并行读取的速度,降低索引读取带来的瓶颈。
(4)根据查询、关联、排序或者聚合条件频率来确定是否建立索引。
索引的建立是为了提高查询速度,查询分析器在解析查询请求时,通过查询、关联、排序或者聚合中的数据列来在索引中查找最匹配的索引,通过该索引来优化查询。所以,在使用频繁用于查询、关联、排序或者聚合条件的数据列上建立索引,可以提高查询速度。
(5)根据数据类型和数据长度来确定是否建立索引。
索引的建立后需要额外的工作来维护索引,所以应该尽量避免在大数据类型如ntext、text、image、varchar(max)、nvarchar(max) 和 varbinary(max)上建立索引。同时,在相同数据类型下,尽量在数据长度较短的数据列上建立索引。例如,如果数据表中有数据列A和B,数据类型为nvarchar,数据列A长度为20,数据列B长度为40,同等情况下,考虑在A列或者B列上建立索引,则应该在数据列A上建立索引减少索引的维护量。
(6)根据数据列的多少来确定是否需要建立索引。
尽量保证索引较短的索引宽度,减少索引的维护量。在索引中包含比较少的列,必要情况下可以是哟功能覆盖索引来提高性能。因为符合查询要求的全部数据都存在于索引本身中。也就是说,只需要索引页,而不需要表的数据页或聚集索引来检索所需数据,因此,减少了总体磁盘 I/O。
(7)根据数据列数值的分布来确定是否需要建立索引。
尽量数据列中数据唯一值较多的情况下建立索引。数据唯一值较多的情况下,可以快速定位到数据。对于数据唯一值较少的列,避免建立索引,否则会导致查询运行时间比较长。如果索引包含多个列,则应考虑列的顺序。用于等于 (=)、大于 (>)、小于 (<) 或 BETWEEN 搜索条件的 WHERE 子句或者参与联接的列应该放在最前面。其他列应该基于其非重复级别进行排序,就是说,从最不重复的列到最重复的列。
(8)根据数据库缺失索引状况建立索引。
在数据库运行过程中,根据不同的工作负荷和查询状况,一些频繁使用的查询在需要使用索引的数据列上没有找到对应的索引,这就是索引的缺失。SQL Server 2005提供了数据库优化向导,根据优化向导的运行状况,可以检查数据库中的缺失索引的状况。也可以根据查询查询动态管理视图来查找缺失的索引。根据索引来建立索引。
flairsky 2009-04-29
  • 打赏
  • 举报
回复
看查询频率

写操作多,不要任何索引最好
如果读操作1两个月才几次,那就查询之前做临时索引,查完后删除
sqn1982 2009-04-29
  • 打赏
  • 举报
回复
欢迎更深入的讨论
tszsc 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 youqi1984 的回复:]
多次用到查询字段,建议使用索引,主键主要是保证列的唯一性。索引是能对查询起到优化的作用
[/Quote]

说的直接了当。
sqn1982 2009-04-29
  • 打赏
  • 举报
回复
我顶
youqi1984 2009-04-29
  • 打赏
  • 举报
回复
多次用到查询字段,建议使用索引,主键主要是保证列的唯一性。索引是能对查询起到优化的作用
  • 打赏
  • 举报
回复
更新频率高的话,还是不要是有聚集索引,uniqueidentifier可以设为主键,但是最好不要使用聚集索引。
sqn1982 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 Yang_ 的回复:]
更新频率非常高

还要看更新的字段,被更新的字段尽量不要索引,而更新用于定位的字段一定要有索引

[/Quote]
所谓更新频率高是指插入数据的频率高
claro 2009-04-29
  • 打赏
  • 举报
回复
还要看行业规范,主键作用。
Yang_ 2009-04-29
  • 打赏
  • 举报
回复
更新频率非常高

还要看更新的字段,被更新的字段尽量不要索引,而更新用于定位的字段一定要有索引
Yang_ 2009-04-29
  • 打赏
  • 举报
回复
uniqueidentifier类型直接查询的情况应该很少,所以聚集索引应该另选,设置成主键没问题
lg3605119 2009-04-29
  • 打赏
  • 举报
回复
看你查询的语句来建立自己需要的聚集索引 , 比如你也面级别是按 日期查询 ,我建议你把聚集索引建立在日期上而不是主键
htl258_Tony 2009-04-29
  • 打赏
  • 举报
回复
if object_id('[ta]') is not null drop table [ta] 
go
create table [ta]([ID] uniqueidentifier not null default newid(),[graNO] varchar(10),[graName] varchar(10),[FID] int NOT NULL)
--1.创建聚集索引:
create unique clustered index idx_ta_id on ta(FID)
--2.创建主键:
alter table ta add constraint pk_ta_id primary key (ID)
--3.查询索引
sp_helpindex ta
/*
index_name index_description index_keys
----------- --------------------------------------------- ------------
idx_ta_id clustered, unique located on PRIMARY FID --在FID上的才是聚集索引
pk_ta_id nonclustered, unique, primary key located on PRIMARY ID --ID已经是非聚集索引
*/
--4.插入测试数据
insert [ta]([graNO],[graName],[FID])
select 's1101','vb',1 union all
select 's1101','c',2
--5.查询
select * from ta
/*
ID graNO graName FID
------------------------------------ ---------- ---------- -----------
F0814E78-25AA-4ADE-944F-64227EB16485 s1101 vb 1
4DACCE91-8AB5-4983-9E0C-359F896D5078 s1101 c 2

(2 行受影响)
*/
htl258_Tony 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 sqn1982 的回复:]
引用 12 楼 hery2002 的回复:
通常情况下,在建立索引时有如下一些技巧:
(1)根据数据量的大小来确定是否建立索引。
数据表中的数据量的大小将决定是否建立索引,是否建立多个索引。对于数据量较小或者数据列较少的表,建立了主键后,不需要建立额外的索引。如果建立了索引,查询分析器在分析时,需要首先扫描索引,然后才会建立执行计划,这样会增加额外的时间来处理这个过程。对于小数据量的表来说,这个过程是不必要的…
[/Quote]
如果你一定要用uniqueidentifier类型做主键,不做聚集索引也行,你可以先在关联查询频率最高的字段建立聚集索引.再将uniqueidentifier用alter命令设置为主键就可以了.
sqn1982 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 hery2002 的回复:]
通常情况下,在建立索引时有如下一些技巧:
(1)根据数据量的大小来确定是否建立索引。
数据表中的数据量的大小将决定是否建立索引,是否建立多个索引。对于数据量较小或者数据列较少的表,建立了主键后,不需要建立额外的索引。如果建立了索引,查询分析器在分析时,需要首先扫描索引,然后才会建立执行计划,这样会增加额外的时间来处理这个过程。对于小数据量的表来说,这个过程是不必要的。因为小数据量的表简单扫描的响应…
[/Quote]
那对于偶这种情况是否合理?麻烦直接作答!
長胸為富 2009-04-29
  • 打赏
  • 举报
回复
一、对具有以下特点的查询使用聚集索引:
1、使用运算符(如 BETWEEN、>、>=、< 和 <=)返回一系列值。
2、使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行物理相邻。例如,如果某个查询在一系列销售订单号间检索记录,SalesOrderNumber 列的聚集索引可快速定位包含起始销售订单号的行,然后检索表中所有连续的行,直到检索到最后的销售订单号。
3、返回大型结果集。
4、使用 JOIN 子句;一般情况下,使用该子句的是外键列。
5、使用 ORDER BY 或 GROUP BY 子句。在 ORDER BY 或 GROUP BY 子句中指定的列的索引,可以使数据库引擎 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。


二、一般情况下,定义聚集索引键时使用的列越少越好。考虑具有下列一个或多个属性的列:
1、唯一或包含许多不重复的值
2、按顺序被访问
3、由于保证了列在表中是唯一的,所以定义为 IDENTITY。
4、经常用于对表中检索到的数据进行排序。
5、按该列对表进行聚集(即物理排序)是一个好方法,它可以在每次查询该列时节省排序操作的成本。


三、聚集索引不适用于具有下列属性的列:
1、频繁更改的列
这将导致整行移动,因为数据库引擎 必须按物理顺序保留行中的数据值。这一点要特别注意,因为在大容量事务处理系统中数据通常是可变的。
2、宽键
宽键是若干列或若干大型列的组合。所有非聚集索引将聚集索引中的键值用作查找键。为同一表定义的任何非聚集索引都将增大许多,这是因为非聚集索引项包含聚集键,同时也包含为此非聚集索引定义的键列。

34,590

社区成员

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

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