Labels

admin (1) aix (1) alert (1) always-on (2) Architecture (1) aws (3) Azure (1) backup (3) BI-DWH (10) Binary (3) Boolean (1) C# (1) cache (1) casting (3) cdc (1) certificate (1) checks (1) cloud (3) cluster (1) cmd (7) collation (1) columns (1) compilation (1) configurations (7) Connection-String (2) connections (6) constraint (6) copypaste (2) cpu (2) csv (3) CTE (1) data-types (1) datetime (23) db (547) DB2 (1) deadlock (2) Denali (7) device (6) dotNet (5) dynamicSQL (11) email (5) encoding (1) encryption (4) errors (124) excel (1) ExecutionPlan (10) extended events (1) files (7) FIPS (1) foreign key (1) fragmentation (1) functions (1) GCP (2) gMSA (2) google (2) HADR (1) hashing (3) in-memory (1) index (3) indexedViews (2) insert (3) install (10) IO (1) isql (6) javascript (1) jobs (11) join (2) LDAP (2) LinkedServers (8) Linux (15) log (6) login (1) maintenance (3) mariadb (1) memory (4) merge (3) monitoring (4) MSA (2) mssql (444) mssql2005 (5) mssql2008R2 (20) mssql2012 (2) mysql (36) MySQL Shell (5) network (1) NoSQL (1) null (2) numeric (9) object-oriented (1) offline (1) openssl (1) Operating System (4) oracle (7) ORDBMS (1) ordering (2) Outer Apply (1) Outlook (1) page (1) parameters (2) partition (1) password (1) Performance (103) permissions (10) pivot (3) PLE (1) port (4) PostgreSQL (14) profiler (1) RDS (3) read (1) Replication (12) restore (4) root (1) RPO (1) RTO (1) SAP ASE (48) SAP RS (20) SCC (4) scema (1) script (8) security (10) segment (1) server (1) service broker (2) services (4) settings (75) SQL (74) SSAS (1) SSIS (19) SSL (8) SSMS (4) SSRS (6) storage (1) String (35) sybase (57) telnet (2) tempdb (1) Theory (2) tips (120) tools (3) training (1) transaction (6) trigger (2) Tuple (2) TVP (1) unix (8) users (3) vb.net (4) versioning (1) windows (14) xml (10) XSD (1) zip (1)

WITH (TABLOCK) - Minimal logging while insert

In order to improve performance for an insert statement,
We can consider use WITH (TABLOCK) option:

INSERT INTO dbo.testItai WITH (TABLOCK) (id, NAME) SELECT ...

Whet it will do is to minimize the writes to the log.

Try it:
Run insertion statement with and without the TABLOCK and check the log:

INSERT INTO dbo.testItai (id, NAME)
SELECT TOP 5000 ABS(CHECKSUM(NEWID())) % 100,
       char(65+ ABS(CHECKSUM(NEWID())) % 26) + char(65+ ABS(CHECKSUM(NEWID())) % 26) + char(65+ ABS(CHECKSUM(NEWID())) % 26) + char(65+ ABS(CHECKSUM(NEWID())) % 26) + char(65+ ABS(CHECKSUM(NEWID())) % 26) +char(65+ ABS(CHECKSUM(NEWID())) % 26)
FROM master..sysobjects a cross join master..sysobjects b

INSERT INTO dbo.testItai WITH (TABLOCK) (id, NAME)
SELECT TOP 5000 ABS(CHECKSUM(NEWID())) % 100,
       char(65+ ABS(CHECKSUM(NEWID())) % 26) + char(65+ ABS(CHECKSUM(NEWID())) % 26) + char(65+ ABS(CHECKSUM(NEWID())) % 26) + char(65+ ABS(CHECKSUM(NEWID())) % 26) + char(65+ ABS(CHECKSUM(NEWID())) % 26) +char(65+ ABS(CHECKSUM(NEWID())) % 26)
FROM master..sysobjects a cross join master..sysobjects b 

Check the log using
select * from fn_dblog(null, null)

You will see that after the insertion without the TABLOCK 5000 records will be written in the log, and much less with the TABLOCK.

WITH (TABLOCK) has few constraints:
1. The destination table must be empty or without clustered index.
2. There is no non-clustered index on the destination table.

Or conditional join

The case:

SELECT ...
FROM TableA a
JOIN TableB b ON (a.ID = b.ID OR a.ID = b.ParentID)

or:
JOIN TableB b ON     a.ID = b.ID
                           AND    (b.AColumn = @AColumn OR @AColumn = 0)
                           -- @AColumn = 0 mean no condition ("all")


Of course it's not forbidden to use conditional join, 
but most of the time it won't be good to the performance of the query.
There are few possible solutions.

0. Keep use the conditional join

For cases the the performance are not get Worse (example: small tables),
or when the 'complecated' cases are uncommon.


1. UNION

Good for 'simple' cases:

Instead of:

SELECT ...
FROM TableA a
JOIN TableB b ON (a.ID = b.ID OR a.ID = b.ParentID)

use:

SELECT ...
FROM TableA a
JOIN TableB b ON a.ID = b.ID
UNION
SELECT ...
FROM TableA a
JOIN TableB b ON a.ID = b.ParentID

or similar case:
Instead of:

SELECT ...
FROM TableA a
JOIN TableB b ON     a.ID = b.ID
                           AND    (b.AColumn = a.AColumn OR b.BColumn = a.BColumn)

Use:
       SELECT ...
       FROM TableA a
       JOIN TableB b ON     a.ID = b.ID
                                  AND b.AColumn = a.AColumn
UNION
SELECT ...
FROM TableA a
JOIN TableB b ON     a.ID = b.ID
                           AND    b.BColumn = a.BColumn


2. filter in the "where":

Instead of:
SELECT ...
FROM TableA a
JOIN TableB b ON     a.ID = b.ID
                                  AND    (b.AColumn = @AColumn OR @AColumn = 0)

SELECT ...
FROM TableA a
JOIN TableB b ON     a.ID = b.ID
WHERE (b.AColumn = @AColumn OR @AColumn = 0))


3. 2 queries:

For cases that the JOIN is depended on a parameter:

Instead of:

SELECT ...
FROM TableA a
JOIN TableB b ON     a.ID = b.ID
                           AND    (b.AColumn = @AColumn OR @AColumn = 0)
                           -- @AColumn = 0 mean no condition ("all")
Use:
IF @AColumn = 0
       SELECT ...
       FROM TableA a
       JOIN TableB b ON     a.ID = b.ID
ELSE
SELECT ...
FROM TableA a
JOIN TableB b ON     a.ID = b.ID
                           AND    b.AColumn = @AColumn -- without consider the case of @AColumn = 0


4. Insert data to temp table

It's good for similar cases like in point 2, but for queries with a lot of joined tables
What we'll do is to store the data for the conditional join in a temp table and use it in the main query:

Instead of:

SELECT ...
FROM TableA a
JOIN TableB b ON     a.ID = b.ID
                           AND    (b.AColumn = @AColumn OR @AColumn = 0)
                           -- @AColumn = 0 mean no condition ("all")
JOIN TableC c .....
JOIN TableD d .....
JOIN TableE e .....

Use:

CREATE TABLE #TempCond (

INSERT INTO #TempCond ()
       SELECT ... -- take the relevant columns
       FROM TableA a
       JOIN TableB b ON     a.ID = b.ID
                                  AND    (b.AColumn = @AColumn OR @AColumn = 0)

--Or, if required, use one of the solutions in points 1,2 to this temp insertion
SELECT ...
FROM #TempCond
JOIN TableC c .....
JOIN TableD d .....
JOIN TableE e .....

Get sysadmin logins

SELECT *
FROM master.sys.server_principals
WHERE IS_SRVROLEMEMBER ('sysadmin',name) = 1
ORDER BY name

Trace Skipped Records

An interesting issue that i saw it first time this week when using the profiler:


Trace Skipped Records....

Apparently that's what it sounds: the profiler was too "busy" or loaded, so it skipped few records...
"Busy"/loaded can be few things:
Long text that was caught and the profiler can't display it in TextData column, busy or loaded server or something in the machine where the profiler isd executing.

This thong is a known issue in Microsoft:


I didn't fing a lot about it, here 2 useful links:

select ... into ... union

declare @a table (aint int)
declare @b table (bint int)

insert into @a (aint) values (1), (2), (3)
insert into @b (bint) values (1), (2), (4), (6)

If you need to insert an union select into a temp table, like this:
select * into #tmp
from (select aint from @a union select bint from @b) t

You can also do it like this:
select aint
into #tmp
from @a
union
select bint
from @b

Check it:
select * from #tmp

(and also drop the temp table :) drop table #tmp )