我有一个表在两列上有一个聚簇索引 - 表的主键.它的定义如下:
ALTER TABLE Table ADD CONSTRAINT [PK_Table] PRIMARY KEY CLUSTERED
(
[ColA] ASC,
[ColB] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
我想删除此聚簇索引PK并添加如下所示的聚簇索引,并使用非聚集索引添加主键约束,如下所示.
CREATE CLUSTERED INDEX [IX_Clustered] ON [Table]
(
[ColC] ASC,
[ColA] ASC,
[ColD] ASC,
[ColE] ASC,
[ColF] ASC,
[ColG] ASC
)WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 90, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF) ON [PRIMARY]
ALTER …Run Code Online (Sandbox Code Playgroud) 仅仅是面试问题和我的知识方面的知识.
SQL - Cluster和之间的区别Non-cluster index?
在许多地方,建议在使用BETWEEN语句选择行范围时更好地利用聚簇索引.当我选择通过外键字段连接以使用此聚簇索引时,我想,该聚类应该也有帮助,因为即使它们都具有相同的聚簇键值并且未使用BETWEEN,也会选择行范围.
考虑到我只关心那个选择加入而没有别的,我猜错了吗?
我正在为我公司正在开始的新数据库制定数据库标准.我们尝试定义的一件事是与UniqueIdentifiers相关的主键和聚簇索引规则.
(注意:我不想讨论使用UniqueIdentifier作为主键或聚簇索引的利弊.网上有大量关于此的信息.这不是讨论.)
所以这是我担心的场景:
假设我有一个带有UniqueIdentifier的表作为聚簇索引和主键.让我们称之为ColA.我将ColA的默认值设置为NewSequentialId().
使用NewSequentialId()我插入三个连续的行:
{72586AA4-D2C3-440D-A9FE-CC7988DDF065}
{72586AA4-D2C3-440D-A9FE-CC7988DDF066}
{72586AA4-D2C3-440D-A9FE-CC7988DDF067}
然后我重启我的服务器.NewSequentialId的文档说"重新启动Windows后,GUID可以从较低的范围重新开始,但仍然是全局唯一的."
因此下一个起点可能低于前一个范围.
所以重启后,我再插入3个值:
{35729A0C-F016-4645-ABA9-B098D2003E64}
{35729A0C-F016-4645-ABA9-B098D2003E65}
{35729A0C-F016-4645-ABA9-B098D2003E66}
(我不确定guid在数据库中是如何表示的,但我们假设因为这个从3开始,之前的7以7开始,3个比7个小".".
当您执行位于聚簇索引中间的插入时,必须重新映射索引.(至少我的DBA告诉过我.)每次重新启动时,我都冒着将新的UniqueIdentifier范围放在其他先前范围中间的风险.
所以我的问题是:由于下一组UniqueIdentifiers将小于最后一组,每个插入是否会导致我的聚簇索引混乱?
如果没有,为什么?SQL Server是否知道我正在使用NewSequentialId?这有什么补偿吗?
如果没有,那么它如何知道接下来会插入什么?也许接下来的百万次插入将从3开始.或者他们可能从7开始.它是如何知道的?
或者它不知道,只是保持一切顺序.如果是这种情况,则一次重启会严重影响性能.(这让我觉得我需要自己的自定义NewSequentialId,它不会受到重启的影响.)这是正确的吗?还是有一些我不知道的魔法?
编辑:我的标准强烈建议不要将GUID作为聚簇索引.正如我上面所说,有很多原因,这是一个坏主意.我试图找出这是否是另一个原因.
sql-server uniqueidentifier clustered-index sql-server-2008 newsequentialid
一般来说......应该将连接表(即关联表)创建为索引组织表(Oracle),聚簇索引(SQL Server)....或普通旧堆表(在2列上具有单独的索引).
我看的方式,优点是:
速度提升.你正在避免堆表查找.
空间改善.你完全取消了堆表,所以你可能节省了大约30%的空间.
缺点:
索引跳过扫描(仅适用于Oracle)..将比全表扫描更快,但比索引扫描慢.因此,对复合键的第二列的搜索将稍微慢一点(Oracle),慢得多(MSSQL).
完整索引扫描将比全表扫描慢 - 所以如果大多数时候基于成本的优化器正在进行哈希联接(不利用索引)......你可能会期望性能更差.(假设RDBMS不首先过滤表).
这让我怀疑,如果您主要要做Hash Joins,那么Join Tables是否真的需要任何类型的索引.
我理解什么是主键和唯一聚簇索引我的问题是为什么在定义唯一聚簇索引时需要主键.只考虑性能良好的数据库设计.
根据我的理解,当我们定义一个集群唯一索引时,它会对数据进行物理排序,这对于表性能是必需的,我们是否定义主键是无关紧要的
许多像这样的stackoverflow链接的帖子声称PostgreSQL中没有聚集索引的概念.但是,PostgreSQL文档包含类似的内容.一些人声称它类似于SQL Server中的聚簇索引.
你知道这两者之间的确切区别是什么,如果有的话?
我们有一个数据库,其中所有PK都是GUID,大多数PK也是表的聚簇索引.我们知道这很糟糕(由于GUID的随机性).因此,似乎这里基本上有两个选项(完全没有将GUID作为PK扔掉,这是我们做不到的(至少目前不是这样)).
是否有可能在这种情况下提供任何一般性建议?
该应用程序有500多个表,最大的一个目前约150万行,几个表约50万行,其余表显着较低(大多数低于10K).
此外,该应用程序已安装在多个客户站点,因此我们必须考虑现有客户的任何可能的负面影响.
谢谢!
我必须使用数据库来进行报告数据库非常大:416 055 104行每行非常轻,但只是布尔值和int id.
每行由3列标识,但令我惊讶的是,它上面没有主键.仅具有唯一约束的聚簇索引.
所以知道,我有两个问题.
关于问题2
创建新主键还会创建要与之关联的非聚集索引(已存在已存在的聚簇索引).
这不是我想要的.我想保留相同的索引,但也使它成为主键.
我有一个Orders带有CLUSTERED IDENTITY PRIMARY KEY(OrderId)的表(),并且正在通过添加日期列()对数据进行过滤和排序AddDate。有没有一种方法可以告诉查询优化器,其AddDate排序方式与OrderIdis 相同(因此数据AddDate已经被排序)?
SQL Server确实不需要先扫描整个表然后对其进行排序。所有操作所需的是扫描表直到找到结束日期,然后在开始日期之前过滤掉数据并按原样返回(不进行排序)。
例:
SELECT
*
FROM Orders
WHERE AddDate BETWEEN @FromDate AND @ToDate
ORDER BY AddDate
Run Code Online (Sandbox Code Playgroud) clustered-index ×10
sql-server ×5
indexing ×4
sql ×3
primary-key ×2
alter ×1
foreign-keys ×1
guid ×1
join ×1
oracle ×1
performance ×1
postgresql ×1
sql-order-by ×1