Wednesday, October 17, 2018
A modified and hardened process that updates statistics
SET NOCOUNT ON
DECLARE @name VARCHAR(128) = '' -- database name
, @update_stats varchar(max) = 'EXECUTE {DBNAME}..sp_updatestats'
, @sql_script varchar(max) = ''
, @errorMessage varchar(max) = ''
, @Recips VARCHAR (1024) = 'foo@foo.org; '
-- , @Subject VARCHAR (1024) = 'TESTING: Failure of maintenance plan for updating statistics '
, @Subject VARCHAR (1024) = 'Failure of maintenance plan for updating statistics '
-- DEV
-- , @mailProfile VARCHAR (64) = 'Mail'
-- QA
, @mailProfile VARCHAR (64) = 'Mail'
-- Prod
-- , @mailProfile VARCHAR (64) = 'Mail'
/*
SELECT @Recips += ISNULL (ap.pValue, 'Elmer; ')
FROM dbo.params ap
WHERE ap.pName = 'Elmer'
*/
DECLARE db_cursor CURSOR FOR
-- Force an error for testing ...
-- SELECT name
SELECT QUOTENAME (name)
FROM master.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb','AspNetSqlSessionState')
OPEN db_cursor
BEGIN TRY
FETCH NEXT FROM db_cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @name
SELECT GETDATE () [Start]
SET @sql_script = REPLACE(@update_stats, '{DBNAME}', @name)
EXEC (@sql_script)
FETCH NEXT FROM db_cursor INTO @name
SELECT GETDATE () [End]
END
END TRY
BEGIN CATCH
SELECT @errorMessage += @name + ': ' + someDB.dbo.fnGetErrorTryCatch ()
END CATCH
CLOSE db_cursor
DEALLOCATE db_cursor
SELECT @errorMessage
IF ISNULL (@errorMessage, '') != ''
BEGIN
EXEC msdb.dbo.sp_send_dbmail
@profile_name = @mailProfile
, @recipients = @Recips
, @body_format = 'HTML'
, @body = @errorMessage
, @subject = @Subject
END
Tuesday, October 16, 2018
How to tell if statistics are actually being updated
Even if everything 'looks' good:
SELECT 'Index Name' = i.name,
'Statistics Date' = STATS_DATE(i.object_id, i.index_id)
FROM sys.objects o
JOIN sys.indexes i ON o.name = 'ORDERs' AND o.object_id = i.object_id;
GO
Monday, March 19, 2018
Deceptively simple ... and potentially evil
drop table tNUM
CREATE TABLE dbo.tNUM
(
NUM INT PRIMARY KEY
);
WITH L0 AS (SELECT 1 AS c UNION ALL SELECT 1), -- 2
L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B), -- 4
L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B), -- 16
L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B), -- 256
L4 AS (SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B), -- 65,536
L5 AS (SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B), -- 4,294,967,296
L6 AS (SELECT 1 AS c FROM L5 AS A CROSS JOIN L5 AS B), -- 18,446,744,073,709,551,616
...
---- Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM L2)
Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM L5) --L6)
INSERT INTO dbo.tNUM ( NUM )
SELECT -- TOP (1000)
n
FROM Nums
--SELECT TOP (1000)
-- n
--FROM Nums
ORDER BY n;
SELECT COUNT (*) FROM tNum
Friday, March 2, 2018
FULL-TEXT (FT), SQL Server, Index Blocking, SQL Server
Context: FULL-TEXT (FT), SQL Server, Index Blocking, SQL Server
FT_MON, FT_SEARCH, FT_CRAWL
Resolution:
a.) Verify that FT is the issue with sp_who2
b.) Put the database in single user mode and drop the index.
ALTER DATABASE [foobar] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
DROP FULLTEXT INDEX ON foo;
GO
ALTER DATABASE [foobar] SET MULTI_USER WITH ROLLBACK IMMEDIATE;
USE [Shared]
GO
ALTER
-- CREATE
PROC dbo. NoBotFindFullTextIndices (
@TableName VARCHAR (256) = ''
, @DatabaseName VARCHAR (256) = ''
, @found INT = 0 OUTPUT
)
AS
BEGIN
/***************************************************************
Author
2018-02-28 15:42:50.917 1968.95
Source:
https://stackoverflow.com/questions/16280918/how-to-find-full-text-indexing-on-database-in-sql-server-2008
Execution:
DECLARE @foundIt INT = 0
EXEC [Shared].dbo.sp_NoBotFindFullTextIndices
'OLS_PRODUCT_SEARCH'
, 'SMCO-PERSONIFY-DEV'
, @found = @foundIt OUTPUT
Note - a simpler way but with less utility ...
SELECT DISTINCT
object_name(fic.[object_id])as table_name
, [name]
FROM [foobar].sys.fulltext_index_columns fic
JOIN [foobar].sys.columns c
on c.[object_id] = fic.[object_id]
and c.[column_id] = fic.[column_id]
****************************************************************/
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @execMe NVARCHAR (2048) = ''
SET @execMe = '
SELECT COUNT (t.name)
FROM ['
+ @DatabaseName
+ '].sys.tables t
JOIN ['
+ @DatabaseName
+ '].sys.fulltext_indexes fi
ON t.[object_id] = fi.[object_id]
JOIN ['
+ @DatabaseName
+ '].sys.fulltext_index_columns ic
ON ic.[object_id] = t.[object_id]
JOIN ['
+ @DatabaseName
+ '].sys.columns cl
ON ic.column_id = cl.column_id
AND ic.[object_id] = cl.[object_id]
JOIN ['
+ @DatabaseName
+ '].sys.fulltext_catalogs c
ON fi.fulltext_catalog_id = c.fulltext_catalog_id
JOIN ['
+ @DatabaseName
+ ']. sys.indexes i
ON fi.unique_index_id = i.index_id
AND fi.[object_id] = i.[object_id]
WHERE t.name = '''
+ @TableName
+ ''';'
EXEC @found = sp_executeSQL @execMe
END
Subscribe to:
Posts (Atom)