首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >打印未来30年的天数的计数方法-为什么要在计数中添加主键约束?

打印未来30年的天数的计数方法-为什么要在计数中添加主键约束?
EN

Stack Overflow用户
提问于 2019-05-09 23:54:16
回答 3查看 48关注 0票数 0

这是我用来打印出未来30年的所有日期的查询。

代码语言:javascript
复制
SELECT TOP 11000 --number of days for 30 years
       IDENTITY(INT,1,1) AS N
INTO #Tally
FROM Master.dbo.SysColumns sc1,
     Master.dbo.SysColumns sc2

declare @endDate datetime = '2049-01-01'
       ,@tmpDate datetime = '2019-01-01'

select dateadd(day, t.N - 1, @tmpDate)
from #Tally t
where t.N - 1 <= DATEDIFF(day, @tmpDate, @endDate)

它工作得很好。但是,一位SQL专家建议我将这些查询添加到我创建#Tally的第一部分下面。

代码语言:javascript
复制
ALTER TABLE #Tally
ADD CONSTRAINT PK_Tally_N 
PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100

如果我运行select * from #Tally上面的"ALTER“查询,结果表中没有任何变化。

我想知道我应该添加ALTER查询的原因是什么(不能问他)?这样做的目的是什么?我看到它添加了一个主键约束,但是为什么要使用clustered(n)fillfactor=100呢?

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-05-10 00:35:18

如果没有指定的索引,SQL Server将在您每次查找值时扫描整个表。因此,例如,如果您运行以下命令...

代码语言:javascript
复制
 SELECT * FROM #Tally WHERE N = 858;

SQL Server会扫描整个表来获得这一条记录,这并不是非常有效。假设您有30个进程正在运行类似的查询。你最终会遇到各种各样的阻塞问题。

如果添加了指定的索引,相同的查询将在不扫描整个表的情况下找到N并返回结果。表上的查找将是高效的,并且您所创建的模式将支持更大的并发性。

现在,对于您提供的查询...

代码语言:javascript
复制
select dateadd(day, t.N - 1, @tmpDate)
from #Tally t
where t.N - 1 <= DATEDIFF(day, @tmpDate, @endDate)

无论如何,SQL Server可能只会执行表扫描。因此,在这种情况下,聚集索引的存在并不能给您带来巨大的回报。

您有一个会话表(#Tally),每天一条记录,天数为30年。查询选择返回...相当于30年的时间。因为在这种情况下,SQL Server必须执行完全扫描才能获得每条记录的数据,所以我认为添加索引不会给您带来太多好处。而不是使用示例中的模式和查询。

N列是一个很好的自然键。我不确定添加它会有什么坏处,但我认为如果不添加它,您不会失去任何东西。但是,如果您确实开始从表中查询值的子集(我不是指整个记录集减去一个或两个),聚集索引肯定会增加好处。

索引由页组成。页面可以存储一定数量的数据。您通常希望在每个页面中使用-打包尽可能多的数据。因此,SQL Server不必扫描太多页面即可找到数据。把每一页想象成一个抽屉。如果抽屉里有1件物品,你需要500个抽屉来存放500件物品。如果你想找到20件商品,你必须打开20件抽屉。如果每个抽屉有100件物品,你最多只能打开5个抽屉,至少1个抽屉。说FILLFACTOR equals 100意味着你不会在页面(抽屉)中留下任何空间;你是在完全填满它。对于数据递增的字段,使用填充因子100是一般的最佳实践,因为您永远不会在索引的中间添加数据,而只是将其添加到末尾。因此,您不需要在索引的现有页中为新数据留出空间。

票数 1
EN

Stack Overflow用户

发布于 2019-05-10 00:32:43

就我个人而言,我会采取一种不同的方法来创建一个理财表。我将此作为我的系统的一个视图。这是闪电般的速度,你永远不需要担心存储。这是我从Jeff Moden那里学到的一种技术,他从Itzik Ben-Gan那里学到了这一点。如果您需要10,000个以上的行,那么您可以很容易地将其扩展到更多行。

代码语言:javascript
复制
create View [dbo].[cteTally] as

WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
    )
select N from cteTally
票数 2
EN

Stack Overflow用户

发布于 2019-05-10 00:40:49

埃雷,

为简单起见,FILLFACTOR属性告诉SQL Server组成索引的页中数据所占的百分比。如果这是一个永远不会改变的表(索引不需要重新构建);则将此值设置为100是有意义的,因为任何小于100的值都会减少每个数据页上可以存储的数据量的容量(尽管程度较小)。

从微软的嘴里说出来;他们提到这一点很重要,因为“未来一个指数可能会增长”:

https://docs.microsoft.com/en-us/sql/relational-databases/indexes/specify-fill-factor-for-an-index?view=sql-server-2017

如需更多信息,请访问:https://www.brentozar.com/archive/2013/04/five-things-about-fillfactor/

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56063309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档