You won't only see ENCRYPTION_SCAN resource in your wait list when Encryption (like TDE) is used.
Certain operations will take a shared lock on this resource to make sure the database is not being encrypted during the operation.
The moment you would encrypt a user database with TDE, the tempdb will also be encrypted (otherwise, you would have security risk when User data is used in temp db).
Therefore, some operations will take a shared lock on ENCRYPTION_SCAN in Tempdb to prevent Tempdb from getting encrypted.
Here are two examples:
BULK INSERT
IF object_id('tempdb..##NumberCreation') IS NOT NULL
drop table ##NumberCreation
GO
--create temp table to hold numbers
create table ##NumberCreation (C int NOT NULL);
GO
-- CREATE Numbers by using trick from Itzik -> http://sqlmag.com/sql-server/virtual-auxiliary-table-numbers
WITH L1 AS ( SELECT 1 as C UNION SELECT 0 ),
L2 AS ( SELECT 1 as C FROM L1 CROSS JOIN L1 as B ),
L3 AS ( SELECT 1 as C FROM L2 CROSS JOIN L2 as B ),
L4 AS ( SELECT 1 as C FROM L3 CROSS JOIN L3 as B ),
L5 AS ( SELECT 1 as C FROM L4 CROSS JOIN L4 as B ),
L6 AS ( SELECT 1 as C FROM L5 CROSS JOIN L5 as B),
Nums as (SELECT ROW_NUMBER() OVER (ORDER BY C) as C FROM L6)
insert ##NumberCreation(C)
SELECT TOP 500000 C
FROM Nums
The above code will generate 500k records in a global temp table, you can export these with the following commands. If you run this from SSMS, make sure you are in SQLCMD mode:
--Export
!!bcp ##NumberCreation out "E:\SQLServer\Backup\test\export.dat" -T -n
--format file
!!bcp ##NumberCreation format nul -T -n -f "E:\SQLServer\Backup\test\export.fmt"
Make sure to choose a directory where SQL Server service account has write permissions and if you run this from SSMS, run it locally on the SQL Server.
Next thing is to start a bulk insert loop. While the loop is running, open a second screen and start running sp_lock untill you see the ENCRYPTION_SCAN shared lock in DB_ID 2 (Which is Tempdb).
The bulk import loop:
BEGIN
IF OBJECT_ID('tempdb..#Import') IS NOT NULL
DROP TABLE #Import ;
CREATE TABLE #Import (C INT) ;
BULK INSERT #Import
FROM 'E:\SQLServer\Backup\test\export.dat' WITH (FORMATFILE='E:\SQLServer\Backup\test\export.fmt', FIRSTROW=1, TABLOCK) ;
END
GO 500 --run it 500 times
See the result of sp_lock in second window:
SORT IN TEMPDB
With the same Temp table in place start this very simple loop:
SELECT * from #Import order by C
go 50
It will produce the following Execution plan:
(Make sure that #Import is actually populated, since depending on when you stopped the previous bulk import loop, it could be empty!)
Again, run sp_lock in a second window until you see the ENCRYPTION_SCAN Resource popping up:
Now you know, why this resource wait is showing up. It could be very well that this is not your problem. I'd just wanted to point out the other reasons that make ENCRYPTION_SCAN show up. The reason for your query slowdown might be something else. I'll leave improving your query plan up to the query plan experts on this site ;-) However, could you post the actual execution plan as well instead of just the estimated plan?
Use SSMS to generate scripts for the entire database DDL.
Use the script to create a new, empty database.
Use BCP
to export the data from all tables. Use BCP
to import that data into the new database.
MAKE SURE YOU BACKUP THE ORIGINAL DATABASE before DROPing
it (if you in fact intend to drop it at all). MAKE SURE YOU TEST RESTORE THE BACKUP.
Best Answer