Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Prosedur Tersimpan untuk Mendapatkan Informasi Tabel Database

Sebagai SQL Server DBA, kami selalu menangani salah satu hal terpenting untuk bisnis, data. Dalam beberapa kasus, aplikasi bisa menjadi sangat kompleks, dan Anda berakhir dengan banyak tabel database yang tersebar di sekitar instance SQL Server Anda. Hal ini dapat menyebabkan beberapa ketidaknyamanan, seperti:

  • Mengetahui bagaimana data Anda berperilaku setiap hari, dalam hal tren pertumbuhan (ruang dan/atau jumlah baris).
  • Mengetahui tabel database apa yang memerlukan (atau akan memerlukan) strategi tertentu/berbeda untuk menyimpan data karena pertumbuhannya terlalu cepat.
  • Mengetahui tabel database mana yang memakan terlalu banyak ruang, yang mungkin menyebabkan kendala penyimpanan.

Karena pentingnya detail ini, saya telah membuat beberapa Prosedur Tersimpan yang dapat sangat membantu untuk DBA SQL Server mana pun yang ingin melacak informasi mengenai tabel database di lingkungannya. Percayalah, salah satunya sangat keren.

Pertimbangan Awal

  • Pastikan bahwa akun yang menjalankan Prosedur Tersimpan ini memiliki cukup hak istimewa. Anda mungkin bisa mulai dengan sysadmin dan kemudian pergi sedetail mungkin untuk memastikan pengguna memiliki hak minimum yang diperlukan agar SP berfungsi dengan baik.
  • Objek database (tabel database dan prosedur tersimpan) akan dibuat di dalam database yang dipilih pada saat skrip dijalankan, jadi pilihlah dengan cermat.
  • Skrip dibuat sedemikian rupa sehingga dapat dieksekusi beberapa kali tanpa membuat Anda error. Untuk Prosedur Tersimpan, saya menggunakan pernyataan "CREATE OR ALTER PROCEDURE", tersedia sejak SQL Server 2016 SP1. Itu sebabnya jangan heran jika tidak bekerja dengan lancar di versi sebelumnya.
  • Silakan mengubah nama objek database yang dibuat.
  • Perhatikan parameter Prosedur Tersimpan yang mengumpulkan data mentah. Mereka bisa menjadi sangat penting dalam strategi pengumpulan data yang kuat untuk memvisualisasikan tren.

Bagaimana Cara Menggunakan Prosedur Tersimpan?

  1. Copy &paste Kode T-SQL (tersedia dalam artikel ini).
  2. SP pertama mengharapkan 2 parameter:
    1. @persistData:‘Y’ jika DBA ingin menyimpan output dalam tabel target, dan ‘N’ jika DBA ingin melihat output secara langsung.
    2. @truncateTable:'Y' untuk memotong tabel terlebih dahulu sebelum menyimpan data yang diambil, dan 'N' jika data saat ini disimpan dalam tabel. Perlu diingat bahwa nilai parameter ini tidak relevan jika nilai parameter @persistData adalah ‘N’.
  3. SP kedua mengharapkan 1 parameter:
    1. @targetParameter:Nama kolom yang akan digunakan untuk mengubah urutan informasi yang dikumpulkan.

Bidang yang Disajikan dan Maknanya

  • nama_database: nama database tempat tabel berada.
  • skema: nama skema tempat tabel berada.
  • nama_tabel: placeholder untuk nama tabel.
  • jumlah_baris: jumlah baris yang dimiliki tabel saat ini.
  • total_spasi_mb: jumlah MegaBytes yang dialokasikan untuk tabel.
  • bekas_spasi_mb: jumlah MegaBytes yang sebenarnya digunakan oleh tabel.
  • unused_space_mb: jumlah MegaBytes yang tidak digunakan tabel.
  • tanggal_dibuat: tanggal/waktu tabel dibuat.
  • data_collection_timestamp: hanya terlihat jika 'Y' diteruskan ke parameter @persistData. Ini digunakan untuk mengetahui kapan SP dieksekusi dan informasi berhasil disimpan di tabel DBA_Tables.

Tes Eksekusi

Saya akan mendemonstrasikan beberapa eksekusi Stored Procedures:

/* Menampilkan informasi tabel untuk semua database pengguna */

EXEC GetTablesData @persistData = 'N',@truncateTable = 'N'

/* Pertahankan informasi tabel database dan kueri tabel target, potong tabel target terlebih dahulu */

EXEC GetTablesData @persistData = 'Y',@truncateTable = 'Y'
SELECT * FROM DBA_Tables

Kueri Samping

*Kueri untuk melihat tabel database yang diurutkan dari jumlah baris terbesar hingga terendah.

SELECT * FROM DBA_Tables ORDER BY row_count DESC;

*Kueri untuk melihat tabel database yang diurutkan dari total ruang terbesar hingga terendah.

SELECT * FROM DBA_Tables ORDER BY total_space_mb DESC;

*Kueri untuk melihat tabel database yang diurutkan dari ruang yang digunakan terbesar hingga yang terendah.

SELECT * FROM DBA_Tables ORDER BY used_space_mb DESC;

*Kueri untuk melihat tabel database yang diurutkan dari ruang terbesar yang tidak terpakai hingga yang terendah.

SELECT * FROM DBA_Tables ORDER BY unused_space_mb DESC;

*Kueri untuk melihat tabel database yang diurutkan berdasarkan tanggal pembuatan, dari yang terbaru hingga yang terlama.

SELECT * FROM DBA_Tables ORDER BY created_date DESC;

Berikut kode lengkap Stored Procedure yang menangkap informasi tabel database:

*Di awal skrip, Anda akan melihat nilai default yang diasumsikan oleh Prosedur Tersimpan jika tidak ada nilai yang diteruskan untuk setiap parameter.

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE OR ALTER PROCEDURE [dbo].[GetTablesData] 
	@persistData   CHAR(1) = 'Y',
	@truncateTable CHAR(1) = 'Y'
AS
BEGIN
	SET NOCOUNT ON

	DECLARE @command NVARCHAR(MAX)    
	
	DECLARE @Tmp_TablesInformation TABLE(       
	[database]        [VARCHAR](255) NOT NULL,
	[schema]          [VARCHAR](64) NOT NULL,
	[table]           [VARCHAR](255) NOT NULL,
	[row_count]       [BIGINT]NOT NULL,
	[total_space_mb]  [DECIMAL](15,2) NOT NULL,
	[used_space_mb]   [DECIMAL](15,2) NOT NULL,
	[unused_space_mb] [DECIMAL](15,2) NOT NULL,
	[created_date]    [DATETIME] NOT NULL
	)      
	
	SELECT @command = '
	USE [?]
	
	IF DB_ID(''?'') > 4
	BEGIN
		SELECT 
			''?'',
			s.Name AS [schema],
			t.NAME AS [table],
			p.rows AS row_count,
			CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS DECIMAL(15, 2)) AS total_space_mb,
			CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS DECIMAL(15, 2)) AS used_space_mb, 
			CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS DECIMAL(15, 2)) AS unused_space_mb,
			t.create_date as created_date
		FROM sys.tables t
		INNER JOIN sys.indexes i ON t.OBJECT_ID = i.object_id
		INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
		INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
		LEFT OUTER JOIN sys.schemas s ON t.schema_id = s.schema_id
		WHERE t.NAME NOT LIKE ''dt%'' 
		  AND t.is_ms_shipped = 0
		  AND i.OBJECT_ID > 255
		GROUP BY t.Name, s.Name, p.Rows,t.create_date
		ORDER BY total_space_mb DESC, t.Name
	END'       
	
	INSERT INTO @Tmp_TablesInformation    
	EXEC sp_MSForEachDB @command      
	   
	IF @persistData = 'N'
		SELECT * FROM @Tmp_TablesInformation 
	ELSE 
	BEGIN
		IF(@truncateTable = 'Y')
		TRUNCATE TABLE DBA_Tables

		INSERT INTO DBA_Tables
		SELECT *,GETDATE() FROM @Tmp_TablesInformation ORDER BY [database],[schema],[table] 
	END
END
GO

Sampai saat ini, informasinya tampak agak kering, tetapi izinkan saya mengubah persepsi itu dengan penyajian Prosedur Tersimpan pelengkap. Tujuan utamanya adalah untuk mentranspos informasi yang dikumpulkan dalam tabel target yang berfungsi sebagai sumber untuk laporan tren.

Berikut cara menjalankan Stored Procedure:

*Untuk tujuan demonstrasi, saya telah memasukkan catatan manual ke dalam tabel target bernama t1 untuk mensimulasikan eksekusi Prosedur Tersimpan saya yang biasa.

*Hasil set agak lebar, jadi saya akan mengambil beberapa tangkapan layar untuk menampilkan hasil lengkapnya.

EXEC TransposeTablesInformation @targetParmeter = 'row_count' 

Pengambilan Penting

  • Jika Anda mengotomatiskan eksekusi skrip yang mengisi tabel target, Anda dapat segera melihat jika ada yang tidak beres dengannya atau dengan data Anda. Perhatikan data untuk tabel 't1' dan kolom '15'. Anda dapat melihat NULL di sana yang dilakukan dengan sengaja untuk menunjukkan kepada Anda sesuatu yang mungkin terjadi.
  • Dengan tampilan seperti ini, Anda dapat melihat perilaku aneh untuk tabel database yang paling penting/kritis.
  • Saya contoh yang diberikan, saya telah memilih bidang 'jumlah_baris' dari tabel target, tetapi Anda dapat memilih bidang numerik lainnya sebagai parameter dan mendapatkan format tabel yang sama, tetapi dengan data yang berbeda.
  • Jangan khawatir, jika Anda menetapkan parameter yang tidak valid, Prosedur Tersimpan akan memperingatkan Anda dan menghentikan eksekusinya.

Berikut kode lengkap Stored Procedure yang mengubah informasi tabel target:

*Di awal skrip, Anda akan melihat nilai default yang diasumsikan oleh Prosedur Tersimpan jika tidak ada nilai yang diteruskan untuk setiap parameter.

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE OR ALTER PROCEDURE [dbo].[TransposeTablesInformation] 
	@targetParameter NVARCHAR(15) = 'row_count' 
AS
BEGIN
	SET NOCOUNT ON;

    IF (@targetParameter <> 'row_count' AND @targetParameter <> 'total_space_mb' AND @targetParameter <> 'used_space_mb' AND @targetParameter <> 'unused_space_mb')
	BEGIN
		PRINT 'Please specify a valid parameter!'
		PRINT 'i.e. row_count | total_space_mb | used_space_mb | unused_space_mb'
		RETURN
	END
	ELSE
	BEGIN
		CREATE TABLE #TablesInformation(
			[database] [VARCHAR](255) NOT NULL,
			[schema]   [VARCHAR](64) NOT NULL,
			[table]    [VARCHAR](255) NOT NULL,
			[1]		   [DECIMAL](10,2) NULL,
			[2]		   [DECIMAL](10,2) NULL,
			[3]		   [DECIMAL](10,2) NULL,
			[4]		   [DECIMAL](10,2) NULL,
			[5]		   [DECIMAL](10,2) NULL,
			[6]		   [DECIMAL](10,2) NULL,
			[7]		   [DECIMAL](10,2) NULL,
			[8]		   [DECIMAL](10,2) NULL,
			[9]		   [DECIMAL](10,2) NULL,
			[10]	   [DECIMAL](10,2) NULL,
			[11]	   [DECIMAL](10,2) NULL,
			[12]	   [DECIMAL](10,2) NULL,
			[13]	   [DECIMAL](10,2) NULL,
			[14]	   [DECIMAL](10,2) NULL,
			[15]	   [DECIMAL](10,2) NULL,
			[16]	   [DECIMAL](10,2) NULL,
			[17]	   [DECIMAL](10,2) NULL,
			[18]	   [DECIMAL](10,2) NULL,
			[19]	   [DECIMAL](10,2) NULL,
			[20]	   [DECIMAL](10,2) NULL,
			[21]	   [DECIMAL](10,2) NULL,
			[22]	   [DECIMAL](10,2) NULL,
			[23]	   [DECIMAL](10,2) NULL,
			[24]	   [DECIMAL](10,2) NULL,
			[25]	   [DECIMAL](10,2) NULL,
			[26]	   [DECIMAL](10,2) NULL,
			[27]	   [DECIMAL](10,2) NULL,
			[28]	   [DECIMAL](10,2) NULL,
			[29]	   [DECIMAL](10,2) NULL,
			[30]	   [DECIMAL](10,2) NULL,
			[31]	   [DECIMAL](10,2) NULL
		)

		INSERT INTO #TablesInformation([database],[schema],[table])
		SELECT DISTINCT [database_name],[schema],[table_name]
		FROM DBA_Tables
		ORDER BY [database_name],[schema],table_name

		DECLARE @databaseName  NVARCHAR(255)
		DECLARE @schemaName    NVARCHAR(64)
		DECLARE @tableName     NVARCHAR(255)
		DECLARE @value	       DECIMAL(10,2)
		DECLARE @dataTimestamp DATETIME
		DECLARE @sqlCommand    NVARCHAR(MAX)

		IF(@targetParameter = 'row_count')
		BEGIN
			DECLARE TablesCursor CURSOR FOR
			SELECT 
					[database_name],
					[schema],
					[table_name],
					[row_count],
					[data_collection_timestamp]
			FROM DBA_Tables
			ORDER BY [database_name],[schema],table_name
		END

		IF(@targetParameter = 'total_space_mb')
		BEGIN
			DECLARE TablesCursor CURSOR FOR
			SELECT 
					[database_name],
					[schema],
					[table_name],
					[total_space_mb],
					[data_collection_timestamp]
			FROM DBA_Tables
			ORDER BY [database_name],[schema],table_name
		END

		IF(@targetParameter = 'used_space_mb')
		BEGIN
			DECLARE TablesCursor CURSOR FOR
			SELECT 
					[database_name],
					[schema],
					[table_name],
					[used_space_mb],
					[data_collection_timestamp]
			FROM DBA_Tables
			ORDER BY [database_name],[schema],table_name
		END

		IF(@targetParameter = 'unused_space_mb')
		BEGIN
			DECLARE TablesCursor CURSOR FOR
			SELECT 
					[database_name],
					[schema],
					[table_name],
					[unused_space_mb],
					[data_collection_timestamp]
			FROM DBA_Tables
			ORDER BY [database_name],[schema],table_name
		END

		OPEN TablesCursor

		FETCH NEXT FROM TablesCursor INTO @databaseName,@schemaName,@tableName,@value,@dataTimestamp

		WHILE(@@FETCH_STATUS = 0)
		BEGIN
			SET @sqlCommand = CONCAT('
			UPDATE #TablesInformation
			SET [',DAY(@dataTimestamp),'] = ',@value,'
			WHERE [database] = ',CHAR(39),@databaseName,CHAR(39),'
			  AND [schema] = ',CHAR(39),@schemaName+CHAR(39),'
			  AND [table] = ',CHAR(39),@tableName+CHAR(39),'
			')
			EXEC(@sqlCommand)

			FETCH NEXT FROM TablesCursor INTO @databaseName,@schemaName,@tableName,@value,@dataTimestamp
		END

		CLOSE TablesCursor

		DEALLOCATE TablesCursor

		IF(@targetParameter = 'row_count')
		SELECT [database],
			   [schema],
			   [table],
			   CONVERT(INT,[1])  AS [1],
			   CONVERT(INT,[2])  AS [2],
			   CONVERT(INT,[3])  AS [3],
			   CONVERT(INT,[4])  AS [4],
			   CONVERT(INT,[5])  AS [5],
			   CONVERT(INT,[6])  AS [6],
			   CONVERT(INT,[7])  AS [7],
			   CONVERT(INT,[8])  AS [8],
			   CONVERT(INT,[9])  AS [9],
			   CONVERT(INT,[10]) AS [10],
			   CONVERT(INT,[11]) AS [11],
			   CONVERT(INT,[12]) AS [12],
			   CONVERT(INT,[13]) AS [13],
			   CONVERT(INT,[14]) AS [14],
			   CONVERT(INT,[15]) AS [15],
			   CONVERT(INT,[16]) AS [16],
			   CONVERT(INT,[17]) AS [17],
			   CONVERT(INT,[18]) AS [18],
			   CONVERT(INT,[19]) AS [19],
			   CONVERT(INT,[20]) AS [20],
			   CONVERT(INT,[21]) AS [21],
			   CONVERT(INT,[22]) AS [22],
			   CONVERT(INT,[23]) AS [23],
			   CONVERT(INT,[24]) AS [24],
			   CONVERT(INT,[25]) AS [25],
			   CONVERT(INT,[26]) AS [26],
			   CONVERT(INT,[27]) AS [27],
			   CONVERT(INT,[28]) AS [28],
			   CONVERT(INT,[29]) AS [29],
			   CONVERT(INT,[30]) AS [30],
			   CONVERT(INT,[31]) AS [31]
		FROM #TablesInformation
		ELSE
		SELECT * FROM #TablesInformation
	END
END
GO

Kesimpulan

  • Anda dapat menerapkan SP pengumpulan data di setiap instans SQL Server di bawah dukungan Anda dan menerapkan mekanisme peringatan di seluruh tumpukan instans yang didukung.
  • Jika Anda menerapkan pekerjaan agen yang menanyakan informasi ini secara relatif sering, Anda dapat tetap menjadi yang teratas dalam hal mengetahui bagaimana data Anda berperilaku selama bulan tersebut. Tentu saja, Anda dapat melangkah lebih jauh dan menyimpan data yang dikumpulkan setiap bulan untuk mendapatkan gambaran yang lebih besar; Anda harus membuat beberapa penyesuaian pada kode, tetapi itu akan sangat berguna.
  • Pastikan untuk menguji mekanisme ini dengan benar di lingkungan sandbox dan, saat Anda merencanakan penerapan produksi, pastikan untuk memilih periode aktivitas rendah.
  • Mengumpulkan informasi jenis ini dapat membantu membedakan DBA satu sama lain. Mungkin ada 3 alat pihak yang dapat melakukan hal yang sama, dan bahkan lebih, tetapi tidak semua orang memiliki anggaran untuk membelinya. Saya harap ini dapat membantu siapa saja yang memutuskan untuk menggunakannya di lingkungan mereka.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Model Basis Data untuk Layanan Taksi

  2. Menghubungkan Aplikasi 32-bit ke jBASE

  3. Fragmentasi Indeks Clustered yang Tak Terduga

  4. Repositori Basis Data Uji IRI-Windocks

  5. Cara Menemukan Catatan dengan NULL di Kolom