这是我用来在接下来的30年中全天打印的查询。
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的第一部分的下面添加这些查询。
ALTER TABLE #Tally
ADD CONSTRAINT PK_Tally_N
PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100
如果我运行select * from #Tally
上面的“ ALTER”查询,结果表中没有任何变化。
我想知道我应该添加ALTER查询(不能问他)的原因是什么?目的是什么?我看到它正在添加一个主键约束,但是为什么要使用clustered(n)
和fillfactor=100
?
谢谢!
答案 0 :(得分:2)
就我个人而言,我将采用另一种方法来创建统计表。我将其作为我系统上的视图。闪电般快速,您不必担心存储空间。这是我从Jeff Moden那里学到的一种技术,他是从Itzik Ben-Gan那里学到的。如果您很容易需要超过10,000行,则可以扩展为具有更多行。
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
答案 1 :(得分:2)
伊瑞
为简单起见,FILLFACTOR属性告诉SQL Server数据(构成索引)的页面百分比。如果这是一个永远不变的表(无需重建索引);将此值设置为100是有意义的,因为任何小于100的值都会减少每个数据页上可以存储的数据量的容量(尽管程度较小)。
从MS的嘴里;他们认为当“未来可能增长到指数”时,这一点很重要:
有关更多信息,请咨询:https://www.brentozar.com/archive/2013/04/five-things-about-fillfactor/
答案 2 :(得分:1)
在没有指定索引的情况下,SQL Server将在您每次查找值时扫描整个表。因此,例如,如果您运行以下内容......
SELECT * FROM #Tally WHERE N = 858;
SQL Server会扫描整个表以获取一条记录,这并不是很有效。假设您有30个这样运行查询的进程。您最终会遇到各种阻塞问题。
如果添加了指定的索引,则同一查询将在不扫描整个表的情况下找到N,并返回结果。在表上进行查找将非常有效,并且您创建的架构将支持更大的并发性。
现在,对于您提供的查询...
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是最佳做法,因为您永远不会在索引中间添加数据,而只会在末尾添加数据。因此,您不需要在索引的现有页面中留出空间来存储新数据。