Yanıtlar:
Güncelleme istatistiklerini dikkate alırken aşağıdakileri aklınızda tutabilirsiniz ( İstatistikleri Yeniden Oluşturma ve Güncelleme İstatistikleri (Benjamin Nevarez)
Varsayılan olarak, UPDATE STATISTICS
ifade tablonun yalnızca bir kayıt örneklerini kullanır. Kullanarak UPDATE STATISTICS WITH FULLSCAN
tüm tabloyu tarar.
Varsayılan olarak, UPDATE STATISTICS
ifade hem dizin hem de sütun istatistiklerini günceller. Bu COLUMNS
seçeneği kullanmak yalnızca sütun istatistiklerini güncelleyecektir. Bu INDEX
seçeneği kullanmak sadece endeks istatistiklerini güncelleyecektir.
Bir dizin yeniden oluşturma kullanılarak örneğin ALTER INDEX … REBUILD
kullanarak da eşdeğer olan endeks istatistiklerini güncelleyecektir WITH FULLSCAN
sürece istatistikleri yalnızca örneklenir bu durumda, Tablo bölümlere ayrılmışsa (SQL Server 2012 ve daha sonra için geçerlidir).
Kullanılarak elle oluşturulan istatistikler , dahil olmak üzere CREATE STATISTICS
hiçbir ALTER INDEX ... REBUILD
işlem tarafından güncellenmez ALTER TABLE ... REBUILD
. ALTER TABLE ... REBUILD
Yeniden yapılanmakta olan tabloda tanımlanmışsa, kümelenmiş dizin için istatistikleri güncelleştirir.
Bir dizini yeniden düzenlemek , örneğin kullanmak ALTER INDEX … REORGANIZE
hiçbir istatistiği güncellemez.
Kısa cevap, UPDATE STATISTICS
sütun istatistiklerini güncellemek için kullanmanız gerektiği ve bir dizin yeniden inşasının yalnızca dizin istatistiklerini güncelleyeceğidir. Dizin istatistikleri ve el ile oluşturulan istatistikler de dahil olmak üzere bir tablodaki tüm istatistiklere UPDATE STATISTICS (tablename) WITH FULLSCAN;
sözdizimi ile güncellemeyi zorlayabilirsiniz .
Aşağıdaki kod yukarıda belirtilen kuralları göstermektedir:
İlk önce, birkaç sütun ve kümelenmiş bir dizin içeren bir tablo oluşturacağız:
USE tempdb;
IF OBJECT_ID(N'dbo.SomeTable', N'U') IS NOT NULL
DROP TABLE dbo.SomeTable;
CREATE TABLE dbo.SomeTable
(
rn int NOT NULL IDENTITY(1,1)
CONSTRAINT pk
PRIMARY KEY NONCLUSTERED
, i int NOT NULL INDEX i
, d sysname NOT NULL
) ON [PRIMARY] WITH (DATA_COMPRESSION = NONE);
CREATE UNIQUE CLUSTERED INDEX cx ON dbo.SomeTable (i, d);
CREATE STATISTICS d ON dbo.SomeTable (d) WITH FULLSCAN;
INSERT INTO dbo.SomeTable (d, i)
SELECT c1.name, c1.id
FROM sys.syscolumns c1;
Bu sorgu, her bir istatistik nesnesinin en son güncellendiği tarihi gösterir:
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
Sonuçlar, henüz bir güncelleme oluşturmadıklarını gösteriyor; bu tabloyu yeni oluşturduğumuzdan beri doğru:
╔═══════════════╦═══════════╦═══════════╗ ║ NesneAdı ║ İstatistiklerAdı ║ StatsDate ║ ╠═══════════════╬═══════════╬═══════════╣ ║ dbo.SomeTable ║ cx ║ NULL ║ ║ dbo.SomeTable ║ i ║ NULL ║ ║ dbo.SomeTable ║ pk ║ NULL ║ ║ dbo.SomeTable ║ d ║ NULL ║ ╚═══════════════╩═══════════╩═══════════╝
Tüm tabloyu yeniden oluşturalım ve bunun istatistikleri güncelleyip güncellemediğini görelim:
ALTER TABLE dbo.SomeTable REBUILD;
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
╔═══════════════╦═══════════╦═════════════════════ ════╗ ║ NesneAdı ║ İstatistiklerAdı ║ StatsDate ║ ╠═══════════════╬═══════════╬═════════════════════ ════╣ ║ dbo. Bazı able cx ║ 2018-09-17 14: 09: 13.590 ║ ║ dbo.SomeTable ║ i ║ NULL ║ ║ dbo.SomeTable ║ pk ║ NULL ║ ║ dbo.SomeTable ║ d ║ NULL ║ ╚═══════════════╩═══════════╩═════════════════════ ════╝
Sonuçlar sadece kümelenmiş endeks istatistiklerinin güncellendiğini göstermektedir.
Sonra, ayrık bir UPDATE STATS
işlem gerçekleştiriyoruz :
UPDATE STATISTICS dbo.SomeTable(d) WITH FULLSCAN;
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
Gördüğünüz gibi, d
sütundaki istatistikleri güncelledik :
╔═══════════════╦═══════════╦═════════════════════ ════╗ ║ NesneAdı ║ İstatistiklerAdı ║ StatsDate ║ ╠═══════════════╬═══════════╬═════════════════════ ════╣ ║ dbo. Bazı able cx ║ 2018-09-17 14: 09: 13.590 ║ ║ dbo.SomeTable ║ i ║ NULL ║ ║ dbo.SomeTable ║ pk ║ NULL ║ ║ dbo.SomeTable ║ d ║ 2018-09-17 14: 09: 13.597 ║ ╚═══════════════╩═══════════╩═════════════════════ ════╝
Şimdi, tüm tablodaki istatistikleri güncelleyeceğiz:
UPDATE STATISTICS dbo.SomeTable WITH FULLSCAN;
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
╔═══════════════╦═══════════╦═════════════════════ ════╗ ║ NesneAdı ║ İstatistiklerAdı ║ StatsDate ║ ╠═══════════════╬═══════════╬═════════════════════ ════╣ ║ dbo. Bazı able cx ║ 2018-09-17 14: 09: 13.600 ║ ║ dbo.SomeTable ║ i ║ 2018-09-17 14: 09: 13.600 ║ ║ dbo.SomeTable ║ pk ║ 2018-09-17 14: 09: 13.603 ║ ║ dbo.SomeTable ║ d ║ 2018-09-17 14: 09: 13.607 ║ ╚═══════════════╩═══════════╩═════════════════════ ════╝
Görebildiğiniz gibi, tüm istatistiklerin güncellendiğinden emin olmanın tek yolu ya her birini manuel olarak güncellemek ya da tüm tabloyu güncellemek UPDATE STATISTICS (table);
.
ALTER INDEX ... REBUILD
da bir UPDATE STATISTICS
ifade ile açıkça güncellenen verilerdir . Tablonun kendisi yeniden oluşturulmuşsa, yalnızca kümelenmiş dizin istatistikleri güncellenir. FYI, bir birincil anahtar ve kümelenmiş bir dizin mutlaka aynı dizin nesnesi tarafından desteklenmez.
SQL Server istatistikleri için Microsoft Docs sayfası şunları gösterir :
Bir dizini yeniden oluşturma, birleştirme veya yeniden düzenleme gibi işlemler veri dağılımını değiştirmez. Bu nedenle, ALTER INDEX REBUILD, DBCC DBREINDEX, DBCC INDEXDEFRAG veya ALTER INDEX REORGANIZE işlemlerini gerçekleştirdikten sonra istatistikleri güncellemeniz gerekmez . Query Optimizer, bir tablodaki bir dizini yeniden oluşturduğunuzda veya ALTER INDEX REBUILD veya DBCC DBREINDEX ile görüntülediğinizde istatistikleri günceller, ancak bu istatistik güncellemesi, dizinin yeniden oluşturulmasının bir yan ürünüdür. Query Optimizer, DBCC INDEXDEFRAG veya ALTER INDEX REORGANIZE işlemlerinden sonra istatistikleri güncellemez.
REINDEX
sütununun, dizini yeniden oluşturmanın bir yan etkisi olarak güncellediğini unutmayın; istatistikleri güncellemeniz gerekmez . Tablodaki veriler değişmez. Aynı veridir, sadece a) döndürme tablasındaki yerini (sayfa yeniden düzenlendiğinde) veya b) farklı bir sayfada otururken (yeniden yapılanma durumunda). Yani: Yeniden endeksi yapar güncelleme (bazı) istatistikleri: hayır yok gerek bunu yapmak için.