.ldf
恢复完整备份后(日志)文件中数据的用途是什么。我计划在我的开发服务器中恢复完整备份后缩小日志文件。
这有什么副作用吗?
.ldf
恢复完整备份后(日志)文件中数据的用途是什么。我计划在我的开发服务器中恢复完整备份后缩小日志文件。
这有什么副作用吗?
试图获取执行作业的会话 id
;with JobDetails as
(
select Job_Id = left(intr1,charindex(':',intr1)-1),
Step = substring(intr1,charindex(':',intr1)+1,charindex(')',intr1)-charindex(':',intr1)-1),
SessionId = spid
from master.dbo.sysprocesses x
cross apply (select replace(x.program_name,'SQLAgent - TSQL JobStep (Job ','')) cs (intr1)
where spid > 50 and x.program_name like 'SQLAgent - TSQL JobStep (Job %'
)
select *
from msdb.dbo.sysjobs j
inner join JobDetails jd on j.job_id = jd.Job_Id
但它会引发以下错误
消息 8169,级别 16,状态 2,第 47 行从字符串转换为唯一标识符时转换失败。
我试图将其job_id
转换为varbinary
但它没有产生任何结果
;with JobDetails as
(
select Job_Id = left(intr1,charindex(':',intr1)-1),
Step = substring(intr1,charindex(':',intr1)+1,charindex(')',intr1)-charindex(':',intr1)-1),
SessionId = spid
from master.dbo.sysprocesses x
cross apply (select replace(x.program_name,'SQLAgent - TSQL JobStep (Job ','')) cs (intr1)
where spid > 50 and x.program_name like 'SQLAgent - TSQL JobStep (Job %'
)
select *
from msdb.dbo.sysjobs j
inner join JobDetails jd on cast(j.job_id as varbinary) = jd.Job_Id
但是当我像这样复制粘贴job_id
时cte
select job_id, name
from msdb..sysjobs
where job_id = 0x128A47A31EAB8F4DA1AD852093D815F5
它有效。知道如何解决此查询
我正在尝试优化程序。该过程中存在 3 种不同的更新查询。
update #ResultSet
set MajorSector = case
when charindex(' ', Sector) > 2 then rtrim(ltrim(substring(Sector, 0, charindex(' ', Sector))))
else ltrim(rtrim(sector))
end
update #ResultSet
set MajorSector = substring(MajorSector, 5, len(MajorSector)-4)
where left(MajorSector,4) in ('(00)','(01)','(02)','(03)','(04)','(05)','(06)','(07)','(08)','(09)')
update #ResultSet
set MajorSector = substring(MajorSector, 4, len(MajorSector)-3)
where left(MajorSector,3) in ('(A)','(B)','(C)','(D)','(E)','(F)','(G)','(H)','(I)','(J)','(K)','(L)','(M)','(N)','(O)','(P)','(Q)','(R)','(S)','(T)','(U)','(V)','(W)','(X)','(Y)','(Z)')
完成所有三个更新查询只需不到10 秒。
所有三个更新查询的执行计划。
https://www.brentozar.com/pastetheplan/?id=r11BLfq7b
我的计划是将三个不同的更新查询更改为一个更新查询,以便减少 I/O。
;WITH ResultSet
AS (SELECT CASE
WHEN LEFT(temp_MajorSector, 4) IN ( '(00)', '(01)', '(02)', '(03)', '(04)', '(05)', '(06)', '(07)', '(08)', '(09)' )
THEN Substring(temp_MajorSector, 5, Len(temp_MajorSector) - 4)
WHEN LEFT(temp_MajorSector, 3) IN ( '(A)', '(B)', '(C)', '(D)','(E)', '(F)', '(G)', '(H)','(I)', '(J)', '(K)', '(L)','(M)', '(N)', '(O)', '(P)','(Q)', '(R)', '(S)', '(T)','(U)', '(V)', '(W)', '(X)','(Y)', '(Z)' )
THEN Substring(temp_MajorSector, 4, Len(temp_MajorSector) - 3)
ELSE temp_MajorSector
END AS temp_MajorSector,
MajorSector
FROM (SELECT temp_MajorSector = CASE
WHEN Charindex(' ', Sector) > 2 THEN Rtrim(Ltrim(Substring(Sector, 0, Charindex(' ', Sector))))
ELSE Ltrim(Rtrim(sector))
END,
MajorSector
FROM #ResultSet)a)
UPDATE ResultSet
SET MajorSector = temp_MajorSector
但这需要大约1 分钟才能完成。我检查了执行计划,它与第一次更新查询相同。
上述查询的执行计划:
https://www.brentozar.com/pastetheplan/?id=SJvttz9QW
有人可以解释为什么它很慢吗?
用于测试的虚拟数据:
If object_id('tempdb..#ResultSet') is not null
drop table #ResultSet
;WITH lv0 AS (SELECT 0 g UNION ALL SELECT 0)
,lv1 AS (SELECT 0 g FROM lv0 a CROSS JOIN lv0 b) -- 4
,lv2 AS (SELECT 0 g FROM lv1 a CROSS JOIN lv1 b) -- 16
,lv3 AS (SELECT 0 g FROM lv2 a CROSS JOIN lv2 b) -- 256
,lv4 AS (SELECT 0 g FROM lv3 a CROSS JOIN lv3 b) -- 65,536
,lv5 AS (SELECT 0 g FROM lv4 a CROSS JOIN lv4 b) -- 4,294,967,296
,Tally (n) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM lv5)
SELECT CONVERT(varchar(255), NEWID()) as Sector,cast('' as varchar(1000)) as MajorSector
into #ResultSet
FROM Tally
where n <= 242906 -- my original table record count
ORDER BY n;
注意:由于这不是我的原始数据,所以我上面提到的时间可能略有不同。单个更新查询仍然比前三个慢得多。
我尝试执行查询超过 10 次以确保外部因素不会影响性能。前三个更新的所有 10 次都比最后一个更新运行得快得多。
是否有查询来检查在给定时间之间运行的作业。我可以检查两次之间安排的作业,但我不希望那样。
示例我想知道在16:00:00
和之间运行的作业是什么17:00:00
在某些情况下,计划的作业15:00:00
可能运行超过 1 小时,我也想要这些。我确实在谷歌搜索过所有我得到的是那些安排在两次之间的工作
我有一个运行速度稍慢的查询。
SELECT b.BreakdownClassificationId,
k.IsinCode,
k.SedolCode,
ClassificationDate,
NAME,
InstrumentType,
GeographicalLocation,
CapSize,
Currency,
ExchangeName,
HoldingDomicile,
MaturityDate,
Sector,
MajorSector
FROM #BreakdownSet b
OUTER apply (SELECT TOP 1 IsinCode,
SedolCode,
ClassificationDate,
NAME,
InstrumentType,
GeographicalLocation,
CapSize CapSize,
Currency,
ExchangeName,
HoldingDomicile,
MaturityDate,
Sector,
MajorSector
FROM dbfinex.dbo.PfPortfolioHoldingClassificationFtid x WITH (nolock)
WHERE ( x.isincode > ''
AND x.isincode = b.breakdowncode )
OR ( x.sedolcode > ''
AND x.sedolcode = b.breakdowncode )
OR ( x.sedolcode > ''
AND x.sedolcode = b.sedolcode )
OR ( x.isincode > ''
AND x.isincode = b.isincode )
ORDER BY CASE
WHEN x.sedolcode = b.breakdowncode THEN 1
WHEN x.isincode = b.breakdowncode THEN 2
WHEN x.sedolcode = b.sedolcode THEN 3
WHEN x.isincode = b.isincode THEN 4
ELSE 5
END,
classificationdate DESC) k
执行计划
Order By
里面Cross Apply
是非常昂贵的,有没有更好的方法来编写这个查询?
有没有办法找到在特定会话中调用触发器的次数?我们的 ETL 应用程序正在像每一行一样插入记录而不是语句(即)如果要插入 100 条记录,我认为 ETL 发出 100 条插入语句而不是在单个批次中插入。所以trigger也叫100次。我只想确认触发器被调用了 100 次。
我有一个想法来改变触发器以具有计数器并将其存储在表中以查找触发器调用的次数。
有没有找到这个的本地方法?
最近我们对我们的数据库使用了一个 sql 代码审查工具。建议使用SP_EXECUTESQL
而不是EXEC
.
我知道SP_EXECUTESQL
可以帮助我们避免 sql 注入。EXEC
使用vs时性能有什么不同吗SP_EXECUTESQL
?
我正在尝试计算运行总数。但是当累积和大于另一列值时它应该重置
create table #reset_runn_total
(
id int identity(1,1),
val int,
reset_val int,
grp int
)
insert into #reset_runn_total
values
(1,10,1),
(8,12,1),(6,14,1),(5,10,1),(6,13,1),(3,11,1),(9,8,1),(10,12,1)
SELECT Row_number()OVER(partition BY grp ORDER BY id)AS rn,*
INTO #test
FROM #reset_runn_total
索引详情:
CREATE UNIQUE CLUSTERED INDEX ix_load_reset_runn_total
ON #test(rn, grp)
样本数据
+----+-----+-----------+-----+
| id | val | reset_val | Grp |
+----+-----+-----------+-----+
| 1 | 1 | 10 | 1 |
| 2 | 8 | 12 | 1 |
| 3 | 6 | 14 | 1 |
| 4 | 5 | 10 | 1 |
| 5 | 6 | 13 | 1 |
| 6 | 3 | 11 | 1 |
| 7 | 9 | 8 | 1 |
| 8 | 10 | 12 | 1 |
+----+-----+-----------+-----+
预期结果
+----+-----+-----------------+-------------+
| id | val | reset_val | Running_tot |
+----+-----+-----------------+-------------+
| 1 | 1 | 10 | 1 |
| 2 | 8 | 12 | 9 | --1+8
| 3 | 6 | 14 | 15 | --1+8+6 -- greater than reset val
| 4 | 5 | 10 | 5 | --reset
| 5 | 6 | 13 | 11 | --5+6
| 6 | 3 | 11 | 14 | --5+6+3 -- greater than reset val
| 7 | 9 | 8 | 9 | --reset -- greater than reset val
| 8 | 10 | 12 | 10 | --reset
+----+-----+-----------------+-------------+
询问:
我使用Recursive CTE
. 原始问题在这里https://stackoverflow.com/questions/42085404/reset-running-total-based-on-another-column
;WITH cte
AS (SELECT rn,id,
val,
reset_val,
grp,
val AS running_total,
Iif (val > reset_val, 1, 0) AS flag
FROM #test
WHERE rn = 1
UNION ALL
SELECT r.*,
Iif(c.flag = 1, r.val, c.running_total + r.val),
Iif(Iif(c.flag = 1, r.val, c.running_total + r.val) > r.reset_val, 1, 0)
FROM cte c
JOIN #test r
ON r.grp = c.grp
AND r.rn = c.rn + 1)
SELECT *
FROM cte
T-SQL
在不使用. 的情况下有没有更好的选择CLR
?
考虑以下设置。涉及三个表#CCP_DETAILS_TEMP
,Period
并且ACTUALS_DETAILS
#CCP_DETAILS_TEMP
will have 50000
records, ACTUALS_DETAILS
can have 5000000
records and period
table will have 2000
records
索引详情:
CREATE UNIQUE CLUSTERED INDEX IX_CCP_DETAILS_TEMP
ON #CCP_DETAILS_TEMP (CCP_DETAILS_SID)
CREATE NONCLUSTERED INDEX IXN_ACTUALS_DETAILS_PERIOD_SID_RS_MODEL_SID_CCP_DETAILS_SID_QUANTITY_INCLUSION
ON ACTUALS_DETAILS (PERIOD_SID, CCP_DETAILS_SID, RS_MODEL_SID, QUANTITY_INCLUSION)
INCLUDE( SALES, QUANTITY, DISCOUNT)
CREATE UNIQUE CLUSTERED INDEX IX_PERIOD
ON PERIOD (PERIOD_SID)
我有一个要求,为此我编写了三种不同的方法来实现结果。现在我想知道哪个更好。
所有三个查询都或多或少地同时运行。我需要一些专家的建议,哪些会表现更好。任何方法都有什么缺点吗
方法一: Outer Apply
用的时间: 4615 Milli Seconds
SELECT c.CCP_DETAILS_SID,
A.PERIOD_SID,
SALES,
QUANTITY
FROM #CCP_DETAILS_TEMP c
CROSS JOIN (SELECT PERIOD_SID
FROM BPIGTN_GAL_APP_DEV_ARM..PERIOD
WHERE PERIOD_SID BETWEEN 577 AND 624)A
OUTER apply (SELECT Sum(SALES),
Sum(QUANTITY)
FROM [DBO].[ACTUALS_DETAILS] ad
WHERE a.PERIOD_SID = ad.PERIOD_SID
AND ad.CCP_DETAILS_SID = c.CCP_DETAILS_SID
AND QUANTITY_INCLUSION = 'Y') oa (sales, quantity)
查询统计:
表“期间”。扫描计数 1,逻辑读取 2,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“#CCP_DETAILS_TEMP”。扫描计数 16,逻辑读取 688,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“工作台”。扫描计数 16,逻辑读取 807232,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“ACTUALS_DETAILS”。扫描计数 1200000,逻辑读取 3859053,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“工作台”。扫描计数 0,逻辑读取 0,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“工作台”。扫描计数 0,逻辑读取 0,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
SQL Server 执行时间:CPU 时间 = 36796 毫秒,经过时间 = 4615 毫秒。
SQL Server 执行时间:CPU 时间 = 0 毫秒,经过时间 = 0 毫秒。
方法二: Left Join
用的时间: 4293 Milli Seconds
SELECT c.CCP_DETAILS_SID,
A.PERIOD_SID,
Sum(SALES),
Sum(QUANTITY)
FROM #CCP_DETAILS_TEMP c
CROSS JOIN (SELECT PERIOD_SID
FROM BPIGTN_GAL_APP_DEV_ARM..PERIOD
WHERE PERIOD_SID BETWEEN 577 AND 624) a
LEFT JOIN [ACTUALS_DETAILS] ad
ON a.PERIOD_SID = ad.PERIOD_SID
AND ad.CCP_DETAILS_SID = c.CCP_DETAILS_SID
AND QUANTITY_INCLUSION = 'Y'
GROUP BY c.CCP_DETAILS_SID,
A.PERIOD_SID
查询统计:
表“ACTUALS_DETAILS”。扫描计数 17,逻辑读取 37134,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“期间”。扫描计数 1,逻辑读取 2,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“#CCP_DETAILS_TEMP”。扫描计数 16,逻辑读取 688,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“工作台”。扫描计数 16,逻辑读取 807232,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“工作文件”。扫描计数 0,逻辑读取 0,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“工作台”。扫描计数 0,逻辑读取 0,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
SQL Server 执行时间:CPU 时间 = 7983 毫秒,经过时间 = 4293 毫秒。
SQL Server 执行时间:CPU 时间 = 0 毫秒,经过时间 = 0 毫秒。
方法 3:聚合 first 和 Left join:
用的时间: 4200 Milli Seconds
SELECT c.CCP_DETAILS_SID,
A.PERIOD_SID,
SALES,
QUANTITY
FROM #CCP_DETAILS_TEMP c
CROSS JOIN (SELECT PERIOD_SID
FROM BPIGTN_GAL_APP_DEV_ARM..PERIOD
WHERE PERIOD_SID BETWEEN 577 AND 624) a
LEFT JOIN (SELECT CCP_DETAILS_SID,
PERIOD_SID,
Sum(SALES) SALES,
Sum(QUANTITY) QUANTITY
FROM [ACTUALS_DETAILS] ad
WHERE QUANTITY_INCLUSION = 'Y'
GROUP BY CCP_DETAILS_SID,
PERIOD_SID) ad
ON a.PERIOD_SID = ad.PERIOD_SID
AND ad.CCP_DETAILS_SID = c.CCP_DETAILS_SID
查询统计:
表“ACTUALS_DETAILS”。扫描计数 17,逻辑读取 37134,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“工作台”。扫描计数 16,逻辑读取 807232,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“工作文件”。扫描计数 0,逻辑读取 0,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“期间”。扫描计数 1,逻辑读取 2,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“#CCP_DETAILS_TEMP”。扫描计数 16,逻辑读取 688,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“工作台”。扫描计数 0,逻辑读取 0,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
SQL Server 执行时间:CPU 时间 = 7731 毫秒,经过时间 = 4200 毫秒。
SQL Server 执行时间:CPU 时间 = 0 毫秒,经过时间 = 0 毫秒。
SQL Server 统计中的直方图步数是如何确定的?
为什么即使我的键列有超过 200 个不同的值,它也限制为 200 个步骤?有什么决定因素吗?
演示
架构定义
CREATE TABLE histogram_step
(
id INT IDENTITY(1, 1),
name VARCHAR(50),
CONSTRAINT pk_histogram_step PRIMARY KEY (id)
)
在我的表中插入 100 条记录
INSERT INTO histogram_step
(name)
SELECT TOP 100 name
FROM sys.syscolumns
更新和检查统计数据
UPDATE STATISTICS histogram_step WITH fullscan
DBCC show_statistics('histogram_step', pk_histogram_step)
直方图步骤:
+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 1 | 0 | 1 | 0 | 1 |
| 3 | 1 | 1 | 1 | 1 |
| 5 | 1 | 1 | 1 | 1 |
| 7 | 1 | 1 | 1 | 1 |
| 9 | 1 | 1 | 1 | 1 |
| 11 | 1 | 1 | 1 | 1 |
| 13 | 1 | 1 | 1 | 1 |
| 15 | 1 | 1 | 1 | 1 |
| 17 | 1 | 1 | 1 | 1 |
| 19 | 1 | 1 | 1 | 1 |
| 21 | 1 | 1 | 1 | 1 |
| 23 | 1 | 1 | 1 | 1 |
| 25 | 1 | 1 | 1 | 1 |
| 27 | 1 | 1 | 1 | 1 |
| 29 | 1 | 1 | 1 | 1 |
| 31 | 1 | 1 | 1 | 1 |
| 33 | 1 | 1 | 1 | 1 |
| 35 | 1 | 1 | 1 | 1 |
| 37 | 1 | 1 | 1 | 1 |
| 39 | 1 | 1 | 1 | 1 |
| 41 | 1 | 1 | 1 | 1 |
| 43 | 1 | 1 | 1 | 1 |
| 45 | 1 | 1 | 1 | 1 |
| 47 | 1 | 1 | 1 | 1 |
| 49 | 1 | 1 | 1 | 1 |
| 51 | 1 | 1 | 1 | 1 |
| 53 | 1 | 1 | 1 | 1 |
| 55 | 1 | 1 | 1 | 1 |
| 57 | 1 | 1 | 1 | 1 |
| 59 | 1 | 1 | 1 | 1 |
| 61 | 1 | 1 | 1 | 1 |
| 63 | 1 | 1 | 1 | 1 |
| 65 | 1 | 1 | 1 | 1 |
| 67 | 1 | 1 | 1 | 1 |
| 69 | 1 | 1 | 1 | 1 |
| 71 | 1 | 1 | 1 | 1 |
| 73 | 1 | 1 | 1 | 1 |
| 75 | 1 | 1 | 1 | 1 |
| 77 | 1 | 1 | 1 | 1 |
| 79 | 1 | 1 | 1 | 1 |
| 81 | 1 | 1 | 1 | 1 |
| 83 | 1 | 1 | 1 | 1 |
| 85 | 1 | 1 | 1 | 1 |
| 87 | 1 | 1 | 1 | 1 |
| 89 | 1 | 1 | 1 | 1 |
| 91 | 1 | 1 | 1 | 1 |
| 93 | 1 | 1 | 1 | 1 |
| 95 | 1 | 1 | 1 | 1 |
| 97 | 1 | 1 | 1 | 1 |
| 99 | 1 | 1 | 1 | 1 |
| 100 | 0 | 1 | 0 | 1 |
+--------------+------------+---------+---------------------+----------------+
正如我们所见,直方图中有 53 个步骤。
再次插入几千条记录
INSERT INTO histogram_step
(name)
SELECT TOP 10000 b.name
FROM sys.syscolumns a
CROSS JOIN sys.syscolumns b
更新和检查统计数据
UPDATE STATISTICS histogram_step WITH fullscan
DBCC show_statistics('histogram_step', pk_histogram_step)
现在直方图步骤减少到 4 个步骤
+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 1 | 0 | 1 | 0 | 1 |
| 10088 | 10086 | 1 | 10086 | 1 |
| 10099 | 10 | 1 | 10 | 1 |
| 10100 | 0 | 1 | 0 | 1 |
+--------------+------------+---------+---------------------+----------------+
再次插入几千条记录
INSERT INTO histogram_step
(name)
SELECT TOP 100000 b.name
FROM sys.syscolumns a
CROSS JOIN sys.syscolumns b
更新和检查统计数据
UPDATE STATISTICS histogram_step WITH fullscan
DBCC show_statistics('histogram_step', pk_histogram_step)
现在直方图步骤减少到 3 个步骤
+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 1 | 0 | 1 | 0 | 1 |
| 110099 | 110097 | 1 | 110097 | 1 |
| 110100 | 0 | 1 | 0 | 1 |
+--------------+------------+---------+---------------------+----------------+
有人能告诉我这些步骤是如何决定的吗?
我试图了解 SQL Server 中的页面拆分,阅读什么是页面拆分?怎么了?为什么会发生?为什么要担心?通过托尼罗杰森
CREATE TABLE mytest
(
something_to_see_in_data CHAR(5) NOT NULL CONSTRAINT pk_mytest PRIMARY KEY CLUSTERED,
filler VARCHAR(3000) NOT NULL
)
go
insert mytest ( something_to_see_in_data, filler ) values( '00001', replicate( 'A', 3000 ) )
insert mytest ( something_to_see_in_data, filler ) values( '00002', replicate( 'B', 1000 ) )
insert mytest ( something_to_see_in_data, filler ) values( '00003', replicate( 'C', 3000 ) )
go
要检查我的表格的页面:
DBCC IND ( 0, 'mytest', 1);
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
| PageFID | PagePID | IAMFID | IAMPID | ObjectID | IndexID | PartitionNumber | PartitionID | iam_chain_type | PageType | IndexLevel |
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
| 1 | 3520 | NULL | NULL | 2065259704 | 1 | 1 | 72057595357560832 | In-row data | 10 | NULL |
| 1 | 3519 | 1 | 3520 | 2065259704 | 1 | 1 | 72057595357560832 | In-row data | 1 | 0 |
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
查看数据页的页面详细信息:
dbcc traceon( 3604 )
go
DBCC page( 0, 1, 3519, 1 ) with tableresults
抵消:
Slot 0, Offset 0x60, Length 3016, DumpStyle BYTE
Slot 1, Offset 0xc28, Length 1016, DumpStyle BYTE
Slot 2, Offset 0x1020, Length 3016, DumpStyle BYTE
更新其中一条记录,使其不适合当前页面,并且会发生页面拆分(即)将创建新页面?
update mytest
set filler = replicate( 'B', 3000 )
where something_to_see_in_data = '00002'
现在再次检查页面:
DBCC IND ( 0, 'mytest', 1);
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
| PageFID | PagePID | IAMFID | IAMPID | ObjectID | IndexID | PartitionNumber | PartitionID | iam_chain_type | PageType | IndexLevel |
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
| 1 | 3520 | NULL | NULL | 2065259704 | 1 | 1 | 72057595357560832 | In-row data | 10 | NULL |
| 1 | 3519 | 1 | 3520 | 2065259704 | 1 | 1 | 72057595357560832 | In-row data | 1 | 0 |
| 1 | 3521 | 1 | 3520 | 2065259704 | 1 | 1 | 72057595357560832 | In-row data | 2 | 1 |
| 1 | 3522 | 1 | 3520 | 2065259704 | 1 | 1 | 72057595357560832 | In-row data | 1 | 0 |
+---------+---------+--------+--------+------------+---------+-----------------+-------------------+----------------+----------+------------+
正如我们所见,创建了两个新页面:
3521 -- Index page
3522 -- Data page
我可以理解创建新页面的原因,Data page(3522)
因为我的数据超过 8kb,因此创建了新页面。
索引页有什么用,什么时候创建?我在谷歌上做了很多研究,索引页面上没有合适的文档。是为了维护B-Tree吗?
SQL SERVER
我们有一个在生产环境中运行单个实例的服务器。
我们计划SQL SERVER
在同一服务器中创建另一个实例。
我的问题是我们必须购买新许可证还是现有许可证足够好?
我正在使用SQL SERVER 2012
我的数据库中有我的Auto Update Stats
ON。
从下面的链接我了解到,自动更新统计信息将SQRT(1000 * Table rows)
在表行的每次更改时触发。
https://blogs.msdn.microsoft.com/srgolla/2012/09/04/sql-server-statistics-explained/
我创建了一个包含 1000 条记录的表
SELECT TOP 500 Row_number()OVER (ORDER BY (SELECT NULL)) rn,
name
INTO stst
FROM sys.objects
创建统计信息
CREATE STATISTICS rn
ON stst (rn)
CREATE STATISTICS name
ON stst (name)
检查创建的统计信息
DBCC show_statistics('stst', rn) -- Rows 500
DBCC show_statistics('stst', name) -- Rows 500
按照公式
select SQRT(1000 * 500) -- 707.106781186548
所以如果我在我的表中添加/修改707.106781186548
记录自动更新统计应该触发
向我的表中添加1000
更多记录,这应该足以触发auto update stats
INSERT INTO stst(rn,name)
SELECT TOP 1000 Row_number()OVER (ORDER BY (SELECT NULL)) rn,
a.name
FROM sys.objects a
开火auto update stats
Select * from stst
检查统计数据
DBCC show_statistics('stst', rn) -- Rows 500
DBCC show_statistics('stst', name) -- Rows 500
不幸的是仍然Rows
是500
唯一的。
即使在将1000
记录插入我的表之后,这显然比707.106781186548
执行SELECT
自动更新统计信息没有触发的原因要大?我在这里想念什么
使用不sp_updatestats
重新采样更新表的统计信息和不使用更新表的统计信息之间有什么区别吗UPDATE STATISTICS
sample options(FULLSCAN,SAMPLE PERCENT,RESAMPLE)
exec sp_updatestats 与更新统计表名
sp_updatestats
使用默认值更新表NO
将使用默认采样率更新统计信息。
同样,使用UPDATE STATISTICS
withoutsample options(FULLSCAN,SAMPLE PERCENT,RESAMPLE)
更新表的统计信息也将使用默认采样更新表统计信息。
那么这两种方法有什么区别吗?我在这里错过了什么吗?
更新 :
我知道它sp_updatestats
在所有表上运行,但使用UPDATE STATISTICS
我们可以更新特定表的统计信息。
我的 SSMS 没有连接到一个特定的服务器,X
除非X
它连接到所有其他服务器。找不到这个问题的根本原因,这里有人知道吗?
坐在我旁边的人可以连接到X
服务器。仅对我而言,它没有连接。
注意:一小时前我可以连接到同一台X
服务器。
我的 ssms 客户端的详细信息
Microsoft SQL Server 2012 - 11.0.5058.0 (X64) May 14 2014 18:34:29 版权所有 (c) Windows NT 6.2(Build 9200:)上的 Microsoft Corporation Developer Edition(64 位)
错误正在获取
非常感谢任何帮助。
我转到命令提示符并键入ping X
. 它返回时请求超时4 次。服务器没有宕机;我的邻居可以连接到X
未连接到我的同一台服务器。