Specifying file groups in Select Into.

IN Select into we can not specify file group and hence always table was created primary file group.
Then we have to create clustered index on other filegroup to change filegroup of created tabled. 
This is time and resource consuming as it needs to move data from one filegroup to other filegroup.

But now in MS SQL 2017 we can specify file group while using select into.

Lets see how to do this.

We have two filegroups in database.
[PRIMARY] and [SAMPLE]

So I want to create table in SAMPLE file group.


Select * into newtable  on [SAMPLE] from sys.tables

This will create table in SAMPLE file group instead of PRIMARY.

How to set shortcuts in query editor

If we set short cuts for commands like sp_lock, sp_helptext , sp_who2 it can be handy as its
frequently required for any developers.
Lets see how to set short cut for this in query editor.

Go to Tools-> Option->Environemnt->Keyboard->Query Shortcuts

Set shortcuts here for your favorite and frequently used commands.



   

Dm_db_stats_properties - to get statistics properties

Managing statistics is important part for developers. Many times we have seen
improper statistics screwed up the queries and queries which completes in seconds
takes hours to complete.
Monitoring statistics and updating it regularly is important for this aspect.
For this we can use  sys.dm_db_stats_properties which give better insight about
each stats for a table.

This DMV has two arguments

Object_id
Stats_id

Better we should user cross apply it with sys.stats and it will give up
in depth details about the stats.


SELECT s.object_id,
       Object_name (s.object_id),
       s.stats_id,
       s.auto_created,
       s.user_created,
       s.no_recompute,
       s.has_filter,
       s.is_temporary,
       s.is_incremental,
       d.last_updated,
       d.rows,
       d.rows_sampled,
       d.steps,
       d.unfiltered_rows,
       d.modification_counter
FROM   sys.stats s
       JOIN sys.tables t
         ON s.object_id = t.object_id
       CROSS apply sys.Dm_db_stats_properties(s.object_id, s.stats_id) d
WHERE  t.type = 'u'




How to audit login

Many times we need to check users logged in our system for various reasons.
This reasons can be many but main requirement we need to know who logged in out system.
There are many ways in SQL Server for this and with introduction of newer versions
many new methods are available for this .

Lets see some of this.1
1.Using SSMS
Connect to server , go to properties.
Go to Security -> Login Auditing.
Select "Both failed and successful logins"



Now restart the server.
You can see the details in errorlog.



2.Using Profiler 
Connect to profiler.
Select events
"Audit Login"
"Audit Login Failed"
Start the trace.
You can see the detail in profiler trace.





Error 8623 and 8632 in SQL Server 2016.

Recently after migrating to SQL Server 2016 one of our app start to failing.
While debugging I found the query which was failing.
The query is like this.




This was working fine SQL Server 2014 but now failing in SQL Server 2016.
I tried it on various serves where SQL Server 2016 is installed.
Getting either 8623 or 8632 error.

BOL give description for this as below.

Error 8623:
The query processor ran out of internal resources and could not produce a query plan. This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions. Please simplify the query. If you believe you have received this message in error, contact Customer Support Services for more information.

Error 8632:
Internal error: An expression services limit has been reached. Please look for potentially complex expressions in your query, and try to simplify them.

It says we  need to change the query to avoid such large number of values in IN clause.
We need to use join in this case.

Workaround 
As its  third party app  and we can not modify the query immediately
We changed compatibility level to 120 (SQL Server 2014) and the query worked !!

This gives us time to contact app developer and get the app modified with new
query.


PWDCOMPARE - to check predictable password

How to check week passwords?
As a strong security policy we also need that password are not predictable.
Many time we need to test this but checking all such predictable password with all logins
is very tedious task and any one will try to avoid.

Recently I had a issue where I need to check that certain predictable passwords are not used by
any login.

Here we can use pwdcompare function , which solves this purpose very easily.

It checks password with stored password hash from sys.sql_logins.

I want to check which logins are using password like qwedsa or password

SELECT *
FROM sys.sql_logins
WHERE PWDCOMPARE('qwedsa',password_hash) = 1

  OR PWDCOMPARE('password',password_hash) = 1

Once we know this logins we can ask the user to change password with strong combinations.

New data compression - Columnstore Archive

All who have used columnstore index must know that columnstore index also compress data.
Many cases after some time this data become historical and use of this data reduces over time.
In this case we can further compress data sung columnsore_archive compression option. Retrieving data takes time after this compression but its acceptable as it reduces storage and its usage frequency is low compare to current data

Lets see with example



CREATE TABLE test
  (
     id   INT,
     data VARCHAR(max)
   
  )

DECLARE @i INT

SET @i = 1

WHILE @i <= 100000
  BEGIN
      INSERT INTO test
      VALUES      (@i,
                   'The value of i is '
                   + CONVERT(VARCHAR(10), @i))

      SET @I = @i + 1
  END

SP_SPACEUSED test

Normal Table


Now we will create clustered columnstore index here.
It will compress data

 
CREATE CLUSTERED COLUMNSTORE INDEX c1 ON test

Table with clustered columnstore index









Now we will compress more using columnstore_archive option 
This will compress data even more. 


ALTER INDEX c1 ON test REBUILD WITH (data_compression = columnstore_archive)

Table with columnstore_archive compression option

 
 



Here we can see size reduces from 8848 KB to 2704 KB and then 1232 KB.


Inline indexes


SQL 2014 has many silent features one of them is inline indexes.
Whats inline indexes?
Inline indexes are which can be created while creating table.
We can specify index in Create Table statement itself.

Here is an example


CREATE TABLE test_table
  (
     id   INT,
     data VARCHAR(max),
       INDEX idx1 (id)
   )






Limitations
1.We can create filtered index
2.We can not create columnstore index.

Good news is that both this issues resolved in SQL Server 2014.

Optimized select into in SQL Server 2014

Lets have quick glance of this feature.
As we all know select .... into clause and how to use it.
Now in SQL 2014 its more optimized and will operate in parallel also for better performance.


Lets see with example

I have one table test_table with 200 Million records in SQL Server 2014 and 2012 both.

We will run Select .... into query and check execution plan



SQL Server 2012

SELECT *
INTO   new_table
FROM   xyz




SQL Server 2014


SELECT *
INTO   new_table
FROM   xyz






As we can see in execution plan optimizer is using parallelism operator to dump data.


SQLPS Powershell in SQL Server -4

Lets see some more cmdlets

1.Backup-Sqldatabase
first we need to check examples how to use Backup_Sqldatabase

Run this command
Get-Help Backup-Sqldatabase -Examples



It will give us examples
Similarly for all cmdlets we can get examples how to use it.


Now we will run a sample how take backup

Backup-Sqldatabase -Database Test




It will take backup of Database Test.

How to redirect  result to HTML page?

Run this command

 Invoke-Sqlcmd "select * from sys.tables" | ConvertTo-Html > c:\test.html




Lets see the result in browser by opening test.html in browser.


















Managed lock priority -SQL 2014

Managed lock priority 

Its available in SQL 2014 and used for online operation s
Mainly used for switching partition and rebuilding indexes online.

Till now its issue to switch partition while tables are in use.
Its because that requires schema modification lock SCH-M lock.
As its not possible to get this lock until any operation is running on table and hence switching partition is a nightmare for any developers.
This request for SCH-M lock was creating a chain of locks and hence affecting performance of OLTP operations.


Now in 2014 we have option that we can define priority for switching or online reindexing with other operations.
Lets see how to use this feature

If we see at syntax of alter table or alter index we will find this option


WAIT_AT_LOW_PRIORITY ( MAX_DURATION = <time> [ MINUTES ], ABORT_AFTER_WAIT =
{ NONE | SELF | BLOCKERS } )

MAX_DURATION is time for which we want to wait before completing the operation

ABORT_AFTER_WAIT :- What action we want to take after waiting time completes
NONE :- Will take no action and continue waiting
SELF :- It will kill self session
BLOCKERS:- It will kill session which are creating blocking and will do switching or
 reindexing.

But this killing session has one drawback it will lead transaction to rollback and if we dont know which operations are in rollback it may impact OLTP operations.
So we need to be careful while doing this and should be done when there is low activity or switching/reindexing has higher priority compare to other tasks.

Lets create a table and check this behavior


CREATE PARTITION FUNCTION part_test_func( datetime)
AS RANGE LEFT FOR VALUES( '2014-09-10' , '2014-09-20' , '2014-09-30');


CREATE PARTITION SCHEME part_test_scheme
AS PARTITION part_test_func TO( [primary],[primary],[primary],[primary]);


CREATE TABLE part_test( id int IDENTITY( 1 , 1) ,
                        data varchar( 100) ,
                        date datetime)
ON part_test_scheme( date);

CREATE TABLE part_test1( id int IDENTITY( 1 , 1) ,
                        data varchar( 100) ,
                        date datetime)
ON part_test_scheme( date);


INSERT INTO  part_test
VALUES( 'a' ,
        '2014-09-05'
      );
INSERT INTO part_test
VALUES( 'a' ,
        '2014-09-15'
      );
INSERT INTO part_test
VALUES( 'a' ,
        '2014-09-25'
      );
INSERT INTO part_test
VALUES( 'a' ,
        '2014-10-05'
      );



Now in other window I will run this query 

BEGIN TRAN

SELECT *
FROM   part_test WITH(updlock)









Now we will go for partition switching in first window 
We will run this query
ALTER TABLE part_test switch PARTITION 1 TO part_test1 PARTITION 1
WITH (WAIT_AT_LOW_PRIORITY (MAX_DURATION = 1 MINUTES,
ABORT_AFTER_WAIT = BLOCKERS))
It will wait for 1 minute and then kill the blocking and statement and complete 
switching.

But we also need to know which session were killed. 
We can find this details in errorlog




Popular Posts