Housekeeping :
Ich verwende SQL Server Microsoft SQL Server 2012 - 11.0.5343.0 (X64)
Lösung :
Sie können WITH RECOMPILE in Ihrer gespeicherten Prozedur verwenden.
Erstellen Sie zunächst eine Testdatenbank, eine Tabelle, einige Indizes und schließlich Testdaten.
USE [master];
GO
IF DATABASEPROPERTYEX (N'test', N'Version') > 0
BEGIN
ALTER DATABASE [test] SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
DROP DATABASE [test];
END
GO
CREATE DATABASE [test];
GO
USE [test];
GO
IF OBJECT_ID('dbo.tbl','U') IS NOT NULL
BEGIN
DROP TABLE dbo.tbl;
END;
CREATE TABLE dbo.tbl
(
c1 INT NOT NULL
, c2 DATETIME NOT NULL
, c3 CHAR(7000) NOT NULL
);
GO
-- Insert 20,000 different dates
INSERT INTO dbo.tbl
SELECT DISTINCT TOP 1000
number
, DATEADD(DAY , number , GETDATE())
, 'a'
FROM
master..spt_values
WHERE
number > 0;
GO 20
-- Add a couple indexes
-- This is a non-unique clustered index
-- so, there will be a 4-byte uniqueifier column
-- added to the row within the page
CREATE CLUSTERED INDEX CIX_tbl_c1
ON dbo.tbl (c1 ASC);
GO
--CREATE NONCLUSTERED INDEX IX_tbl_c2
-- ON dbo.tbl (c2 ASC);
--GO
Fügen Sie eine gespeicherte Prozedur hinzu:
USE [test];
GO
CREATE PROCEDURE dbo.TestProc @i INT
--WITH RECOMPILE
AS
SELECT DISTINCT
c1
FROM
dbo.tbl
WHERE
c1 = @i;
GO
Geben Sie jetzt Ihren Cache frei (tun Sie dies nicht in der Produktion!) Und überprüfen Sie ihn.
-- Free your cache
DBCC FREEPROCCACHE;
GO
-- What is in my cache?
USE [master];
GO
SELECT
usecounts
, refcounts
, cacheobjtype
, objtype
, DB_NAME([dbid])
, [sql]
FROM
syscacheobjects
ORDER BY
[dbid]
, usecounts DESC
, objtype;
GO
Führen Sie Ihre Prozedur einmal aus und überprüfen Sie den Cache.
-- Execute my stored procedure once
USE [test];
GO
EXEC dbo.TestProc @i = 10;
GO
-- Re-check the cache
USE [master];
GO
SELECT
usecounts
, refcounts
, cacheobjtype
, objtype
, DB_NAME([dbid])
, [sql]
FROM
syscacheobjects
ORDER BY
[dbid]
, usecounts DESC
, objtype;
GO
Ihr Plan ist da und wurde einmal verwendet:
Ändern Sie nun Ihre Prozedur MIT RECOMPILE.
-- Now, alter your procedure
USE [test];
GO
ALTER PROCEDURE dbo.TestProc @i INT
WITH RECOMPILE
AS
SELECT DISTINCT
c1
FROM
dbo.tbl
WHERE
c1 = @i;
GO
Geben Sie Ihren Cache noch einmal frei, führen Sie Ihre Prozedur aus und überprüfen Sie den Cache auf einen Eintrag.
-- Free your cache
DBCC FREEPROCCACHE;
GO
-- Execute my stored procedure once
USE [test];
GO
EXEC dbo.TestProc @i = 10;
GO
-- Re-check the cache
USE [master];
GO
SELECT
usecounts
, refcounts
, cacheobjtype
, objtype
, DB_NAME([dbid])
, [sql]
FROM
syscacheobjects
ORDER BY
[dbid]
, usecounts DESC
, objtype;
GO
</pre>
Es ist nicht da! Dies sollte Ihnen helfen.
Was nun die Indizes betrifft, können wir dieses Experiment ausprobieren:
USE [test];
GO
SELECT
c2
FROM
dbo.tbl
WHERE
c2 > '09-15-2015';
GO
Hier ist der Ausführungsplan für diese Abfrage:
Ich kann jetzt die Indexanforderung sehen.
SELECT
index_handle
, database_id
, object_id
, equality_columns
, inequality_columns
, included_columns
, statement
FROM
sys.dm_db_missing_index_details;
GO