Tips & Tricks with SQL Server 
Performance Tuning, SSAS, SSRS, 
SSIS, and More! 
By Ike Ellis, MVP 
@ike_ellis 
www.ikeellis.com 
Blog.ikeellis.com 
http://www.linkedin.com/in/ikeellis
So you want to be great at SQL 
Server… SQL Server Integration Services 
SQL Server Analysis Services 
Tabular 
MultiDimensional 
SQL Server Reporting Services 
Excel 
Data Quality Services 
Service Broker 
Performance Tuning 
Indexing 
Query Plans 
Plan Analysis 
Memory Management 
SANs 
Network 
Clustering 
Availability Groups 
PowerShell 
Master Data Services 
Architecture 
Data Mart Design 
Data Normalization 
CDC 
NoSQL/BigData (At least the MS Cloud Offerings) 
Competitive Knowledge (Oracle, Tablaeu, QlickView, 
Postgres) 
ORMs(Entity Framework, Nhibernate, Micros) 
Installation/Configuration/Upgrading/Service Packing 
Power BI 
PowerMap 
PowerQuery 
PowerView 
PowerPivot 
T-SQL 
Querying 
Stored Procedures 
Functions 
Windowing Functions 
Aggregates 
CLR 
MDX 
DAX 
XMLA 
BCP 
SQL Azure 
Tooling 
Redgate 
SSMS 
SSDT 
Past Versions 
Central Management 
DacPacs/BacPacs 
Profiler/Extended Events 
Auditing 
Security/Encryption 
Replication 
SQLCMD
Tips From the SQL Consultant 
• For the YouTube/Reddit/Chive/Cracked/Meme generation 
• Lots of disjointed tips 
• Popular mistakes I see or easy things I think you can take 
advantage of 
• Between 3 – 5 minutes each 
• Let’s see if we can get through all 20
TIP #1: Query Shortcuts 
• SELECT COUNT(*) FROM 
• SELECT TOP 100 * FROM
TIP #2: Don’t forget the splitter 
bar
TIP #3: Low hanging fruit 
• CRTL-R 
– F6 switches between result tabs 
• Copy, Paste a line without selecting 
• COMMENTS CTRL-K, C, CTRL-K U 
• BOOKMARKS CTRL-K, K, CTRL-K N 
• Refresh cache – CTRL-SHIFT R 
– Unless RedGate then CTRL-SHIFT D
TIP #4: Block Commenting 
• Easy column selection – bring up the query window 
– CTRL-SHIFT Q 
• Format the columns comma first, like you’re supposed to 
– SQL PROMPT – CTRL-K, CTRL-Y 
• Alias a table 
• CTRL-ALT arrow 
• Add alias
TIP #5: Code Snippets 
• CTRL-K, CTRL-B – Bring up Code Snippet Manager 
• Copy an existing one from a path and put it in the My Snippets 
Path 
• Edit the XML 
• CTRL-K, CTRL-X to place the snippet 
• Great for common queries 
– WhoIsActive 
– sp_Blitz 
– DBCC OPENTRAN
Tip #6: SSIS for the Color Blind
Tip #7: Five minutes on report formatting = 10x more 
impressive 
• Spend 10 minutes on design (as opposed to the zero we 
typically spend) 
• Choose colors wisely 
– 99/100 - developers use the default color palette 
• HTML color picker websites 
– http://www.lavishbootstrap.com 
• MorgueFile 
– http://www.morguefile.com/
Tip #8: The right way to find hardware 
problems 
• Merging PerfMon and Tracing 
• Get the Batch and Completed Events Only 
• Never trace from the computer you are monitoring 
• Always trace to a file and then load in a table after. 
11 
*Thanks, Grant!
Tip #9: Lifehack: Readable Presentations 
• Take the average age of the 
people in your audience and 
divide by 2: That’s your font 
size 
• USE THIS SIZE IF YOUR 
AUDIENCE IS 110
Tip #10: Check for heaps/clustered 
indexes 
SELECT t.[Name] FROM sys.Indexes i 
JOIN sys.Tables t 
ON t.Object_ID = i.Object_id 
WHERE i.type_desc = 'HEAP' 
ORDER BY t.[Name]
Tip #11: The proper way to run an SSIS 
package
Tip #12: No reason to use ISNULL  
CONCAT! 
• Messy vs clean code 
• No + symbol needed 
• No ISNULL needed
Tip #13: How to search schema 
• F7 
• SQLSearch 
– Free 
– Download it! 
– http://www.red-gate.com/products/sql-development/sql-search/ 
– Did I mention it’s free? 
• Dependency Tracker 
– Not Free, but still cool 
select object_name(object_id), definition as name 
from sys.all_sql_modules 
where definition like '%cust%'
Tip #14: Windowing Functions are pretty 
cool 
• They are worth learning, and have a neat evolution
Tip #15: SSDT Search for options 
• No more digging around in options 
• Just search for everything
Tip #16: Scripting: You have two 
choices 
• Two Choices 
– Get good at boring repetitive tasks 
– Get good at PowerShell & Scripting 
• Who adds more value to their company or their customers? 
• Who gets paid more?
Tip #17: TempDB Configuration 
• Current thought is 4 logical processors to 1 file 
• Just a good beginning, your mileage may very 
• Start there, then go to 2:1 or 1:1 if necessary 
• Trace Flag 1117 or autogrow off
Tip #18: Prettify! 
21 
http://extras.sqlservercentral.com/prettifier/prettifier.aspx 
RedGate PlugIn for SQL Server Management Studio
Tip #19: Execute scripts over multiple 
servers? 
• Super easy!
Tip #20: Life is so easy with a dates 
table 
• Find the sales numbers for the first Monday of every month 
of the year 
• T-SQL with no dates table 
• T-SQL with dates table
Tip #21: Try_Cast 
• Avoiding terrible casting errors
Tip #22: Never reinvent the wheel 
• Take SQL# for example 
• Good Documentation 
• Easy Syntax 
• Cheap (and much of it is free)
Tip #23: Save scripts for easy 
access 
• Lots of repetitive scripts with business logic 
• No reason to write the same queries for the same tables 
day after day
Tip #24: Enforce Business Rules in the 
DB 
• Foreign Keys 
• Unique Constraints 
• Check Constraints 
27
Tip #25: Log, Log, Log (and beware of subscriptions) 
select c.Name 
, e.InstanceName 
, e.UserName 
, e.Parameters 
, e.TimeStart 
, e.TimeEnd 
, e.TimeDataRetrieval 
, e.TimeProcessing 
, e.TimeRendering 
from executionlog e 
join catalog c 
on e.reportid = c.ItemID 
Send a Link, or a file on a shared folder that you can audit. Find someway to audit 
who opened the link or the file in the folder. Try to avoid sending the PDF without 
a way to audit it.
Ike Ellis 
• http://blog.ikeellis.com 
• http://www.ikeellis.com 
• YouTube 
– http://www.youtube.com/user/IkeEllisData 
• SQL Pass Book Readers 
– http://bookreaders.sqlpass.org/ 
• San Diego Tech Immersion Group 
• Twitter: @ike_ellis 
• 619.922.9801 
• Email address is just my first name @ikeellis.com

Tips & Tricks SQL in the City Seattle 2014

  • 1.
    Tips & Trickswith SQL Server Performance Tuning, SSAS, SSRS, SSIS, and More! By Ike Ellis, MVP @ike_ellis www.ikeellis.com Blog.ikeellis.com http://www.linkedin.com/in/ikeellis
  • 2.
    So you wantto be great at SQL Server… SQL Server Integration Services SQL Server Analysis Services Tabular MultiDimensional SQL Server Reporting Services Excel Data Quality Services Service Broker Performance Tuning Indexing Query Plans Plan Analysis Memory Management SANs Network Clustering Availability Groups PowerShell Master Data Services Architecture Data Mart Design Data Normalization CDC NoSQL/BigData (At least the MS Cloud Offerings) Competitive Knowledge (Oracle, Tablaeu, QlickView, Postgres) ORMs(Entity Framework, Nhibernate, Micros) Installation/Configuration/Upgrading/Service Packing Power BI PowerMap PowerQuery PowerView PowerPivot T-SQL Querying Stored Procedures Functions Windowing Functions Aggregates CLR MDX DAX XMLA BCP SQL Azure Tooling Redgate SSMS SSDT Past Versions Central Management DacPacs/BacPacs Profiler/Extended Events Auditing Security/Encryption Replication SQLCMD
  • 3.
    Tips From theSQL Consultant • For the YouTube/Reddit/Chive/Cracked/Meme generation • Lots of disjointed tips • Popular mistakes I see or easy things I think you can take advantage of • Between 3 – 5 minutes each • Let’s see if we can get through all 20
  • 4.
    TIP #1: QueryShortcuts • SELECT COUNT(*) FROM • SELECT TOP 100 * FROM
  • 5.
    TIP #2: Don’tforget the splitter bar
  • 6.
    TIP #3: Lowhanging fruit • CRTL-R – F6 switches between result tabs • Copy, Paste a line without selecting • COMMENTS CTRL-K, C, CTRL-K U • BOOKMARKS CTRL-K, K, CTRL-K N • Refresh cache – CTRL-SHIFT R – Unless RedGate then CTRL-SHIFT D
  • 7.
    TIP #4: BlockCommenting • Easy column selection – bring up the query window – CTRL-SHIFT Q • Format the columns comma first, like you’re supposed to – SQL PROMPT – CTRL-K, CTRL-Y • Alias a table • CTRL-ALT arrow • Add alias
  • 8.
    TIP #5: CodeSnippets • CTRL-K, CTRL-B – Bring up Code Snippet Manager • Copy an existing one from a path and put it in the My Snippets Path • Edit the XML • CTRL-K, CTRL-X to place the snippet • Great for common queries – WhoIsActive – sp_Blitz – DBCC OPENTRAN
  • 9.
    Tip #6: SSISfor the Color Blind
  • 10.
    Tip #7: Fiveminutes on report formatting = 10x more impressive • Spend 10 minutes on design (as opposed to the zero we typically spend) • Choose colors wisely – 99/100 - developers use the default color palette • HTML color picker websites – http://www.lavishbootstrap.com • MorgueFile – http://www.morguefile.com/
  • 11.
    Tip #8: Theright way to find hardware problems • Merging PerfMon and Tracing • Get the Batch and Completed Events Only • Never trace from the computer you are monitoring • Always trace to a file and then load in a table after. 11 *Thanks, Grant!
  • 12.
    Tip #9: Lifehack:Readable Presentations • Take the average age of the people in your audience and divide by 2: That’s your font size • USE THIS SIZE IF YOUR AUDIENCE IS 110
  • 13.
    Tip #10: Checkfor heaps/clustered indexes SELECT t.[Name] FROM sys.Indexes i JOIN sys.Tables t ON t.Object_ID = i.Object_id WHERE i.type_desc = 'HEAP' ORDER BY t.[Name]
  • 14.
    Tip #11: Theproper way to run an SSIS package
  • 15.
    Tip #12: Noreason to use ISNULL  CONCAT! • Messy vs clean code • No + symbol needed • No ISNULL needed
  • 16.
    Tip #13: Howto search schema • F7 • SQLSearch – Free – Download it! – http://www.red-gate.com/products/sql-development/sql-search/ – Did I mention it’s free? • Dependency Tracker – Not Free, but still cool select object_name(object_id), definition as name from sys.all_sql_modules where definition like '%cust%'
  • 17.
    Tip #14: WindowingFunctions are pretty cool • They are worth learning, and have a neat evolution
  • 18.
    Tip #15: SSDTSearch for options • No more digging around in options • Just search for everything
  • 19.
    Tip #16: Scripting:You have two choices • Two Choices – Get good at boring repetitive tasks – Get good at PowerShell & Scripting • Who adds more value to their company or their customers? • Who gets paid more?
  • 20.
    Tip #17: TempDBConfiguration • Current thought is 4 logical processors to 1 file • Just a good beginning, your mileage may very • Start there, then go to 2:1 or 1:1 if necessary • Trace Flag 1117 or autogrow off
  • 21.
    Tip #18: Prettify! 21 http://extras.sqlservercentral.com/prettifier/prettifier.aspx RedGate PlugIn for SQL Server Management Studio
  • 22.
    Tip #19: Executescripts over multiple servers? • Super easy!
  • 23.
    Tip #20: Lifeis so easy with a dates table • Find the sales numbers for the first Monday of every month of the year • T-SQL with no dates table • T-SQL with dates table
  • 24.
    Tip #21: Try_Cast • Avoiding terrible casting errors
  • 25.
    Tip #22: Neverreinvent the wheel • Take SQL# for example • Good Documentation • Easy Syntax • Cheap (and much of it is free)
  • 26.
    Tip #23: Savescripts for easy access • Lots of repetitive scripts with business logic • No reason to write the same queries for the same tables day after day
  • 27.
    Tip #24: EnforceBusiness Rules in the DB • Foreign Keys • Unique Constraints • Check Constraints 27
  • 28.
    Tip #25: Log,Log, Log (and beware of subscriptions) select c.Name , e.InstanceName , e.UserName , e.Parameters , e.TimeStart , e.TimeEnd , e.TimeDataRetrieval , e.TimeProcessing , e.TimeRendering from executionlog e join catalog c on e.reportid = c.ItemID Send a Link, or a file on a shared folder that you can audit. Find someway to audit who opened the link or the file in the folder. Try to avoid sending the PDF without a way to audit it.
  • 29.
    Ike Ellis •http://blog.ikeellis.com • http://www.ikeellis.com • YouTube – http://www.youtube.com/user/IkeEllisData • SQL Pass Book Readers – http://bookreaders.sqlpass.org/ • San Diego Tech Immersion Group • Twitter: @ike_ellis • 619.922.9801 • Email address is just my first name @ikeellis.com

Editor's Notes

  • #12 use tsql2012 SELECT * FROMSales.customers go select * from sales.orders go select top 100000 * from sales.orders, sales.customers
  • #16  update sales.customers set contacttitle = null where custid in ('59', '66', '78', '15') use tsql2012 select * from sales.customers select ContactName + ' - ' + ContactTitle + ', ' + City as GreetingLine from sales.customers select isnull(ContactName, '') + ' - ' + isnull(ContactTitle, '') + ', ' + isnull(City, '') as GreetingLine from sales.customers select concat(ContactName, ' ', ContactTitle, ' ', City) as GreetingLine from sales.customers
  • #18 use tsql2012 select * from sales.orders select custid, freight from sales.orders select custid, freight, sum(freight) as totalFreight from sales.orders select custid, sum(freight) as totalFreight from sales.orders group by custid select custid, freight, sum(freight) as totalFreight from sales.orders group by custid select custid, freight, sum(freight) as totalFreight from sales.orders group by custid, freight --we're skipping subqueries, because they look ugly and --it insults me aesthetically ;with FreightTotal as ( select custid, sum(freight) as totalFreight from sales.orders group by custid ) select o.custid , o.freight , ft.totalFreight as totalFreight from sales.orders o join FreightTotal ft on o.custid = ft.custid --BIG IMPROVEMENT --query can be executed independantly --Can be reused, like this ;with FreightTotal as ( select custid, sum(freight) as totalFreight from sales.orders group by custid ) select o.custid , o.freight , ft.totalFreight as totalFreight , o.freight /ft.totalfreight * 100 as FreightPercentage from sales.orders o join FreightTotal ft on o.custid = ft.custid --but remember our original thought process select custid, freight, sum(freight) as totalFreight from sales.orders --here's a windowing function select custid , freight , sum(freight) over (partition by custid) as totalFreight from sales.orders --and reusing it is not that big of a deal select custid , freight , sum(freight) over (partition by custid) as totalFreight , freight / sum(freight) over (partition by custid) * 100 as FreightPercentage from sales.orders
  • #20  # We can narrow down the list by filtering on the source Get-EventLog Application | Where-Object {$_.Source -like '*sql*' ` -and $_.EntryType -eq "Error" ` -and $_.TimeGenerated -ge ((Get-Date).AddHours(-96)) ` } | Format-List Write-Host "Press any key to continue ..." $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") Write-Host Write-Host "A" Write-Host "B" Write-Host "C"
  • #22 SELECT * FROM (SELECT urgency, name, phone, location, department, cc, status, case_manager, ip, case_manager_ei d, id_problem, id_problem_type, eid_author, title, body, date_created, date_modified FROM problems AS main INNER JOIN (SELECT id_problem as t_urgency_id_problem, node_value AS urgency FROM problem_nodes WHERE node_name = "urgency")t_urgency ON t_urgency.t_urgency_id_problem = main.id_problem INNER JOIN (SELECT id_problem as t_name_id_problem, node_value AS name FROM problem_nodes WHERE node_name = "name")t_name ON t_name.t_name_id_problem = main.id_problem INNER JOIN (SELECT id_problem as t_phone_id_problem, node_value AS phone FROM problem_nodes WHERE node_name = "phone")t_phone ON t_phone.t_phone_id_problem = main.id_problem INNER JOIN (SELECT id_problem as t_location_id_problem, node_value AS location FROM problem_nodes WHERE node_name = "location")t_location ON t_location.t_location_id_problem = main.id_problem INNER JOIN (SELECT id_problem as t_department_id_problem, node_value AS department FROM problem_nodes WHERE node_name = "department")t_department ON t_department.t_department_id_problem = main.id_problem INNER JOIN (SELECT id_problem as t_cc_id_problem, node_value AS cc FROM problem_nodes WHERE node_name = "cc")t_cc ON t_cc.t_cc_id_problem = main.id_problem INNER JOIN (SELECT id_problem as t_status_id_problem, node_value AS status FROM problem_nodes WHERE node_name = "status")t_status ON t_status.t_status_id_problem = main.id_problem INNER JOIN (SELECT id_problem as t_case_manager_id_problem, node_value AS case_manager FROM problem_nodes WHERE node_name = "case_manager")t_case_manager ON t_case_manager.t_case_manager_id_problem = main.id_problem INNER JOIN (SELECT id_problem as t_ip_id_problem, node_value AS ip FROM problem_nodes WHERE node_name = "ip")t_ip ON t_ip.t_ip_id_problem = main.id_problem INNER JOIN (SELECT id_problem as t_case_manager_eid_id_problem, node_value AS case_manager_eid FROM problem_nodes WHERE node_name = "case_manager_eid") t_case_manager_eid ON t_case_manager_eid.t_case_manager_eid_id_problem = main.id_problem)t
  • #24  ;with FirstMondays as ( Select DateAdd(day, (9-DatePart(weekday, DateAdd(Month, 1+DateDiff(Month, 0, '12/1/2009'), 0)))%7, DateAdd(Month, 1+DateDiff(Month, 0, '12/1/2009'), 0)) as FirstMonday union all select DateAdd(day, (9-DatePart(weekday, DateAdd(Month, 1+DateDiff(Month, 0, FirstMonday), 0)))%7, DateAdd(Month, 1+DateDiff(Month, 0, FirstMonday), 0)) from FirstMondays where firstMonday <= '12/1/2010' ) select * from FirstMondays use adventureworksdw2012 select EnglishMonthName, min(datekey) from dimdate where englishdaynameofweek = 'monday' and calendaryear = '2010' group by EnglishMonthName, MonthNumberOfYear order by MonthNumberOfYear
  • #25 create table t1 (col1 varchar(100)) insert into t1 (col1) values ('1') ,('2') ,('3') ,('ike') ,('1') ,('2') ,('3') ,('ike') , ('1') ,('2') ,('3') ,('ike') select cast(col1 as int) from t1 select try_cast(col1 as int) from t1
  • #26 SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'D', '') -- Thursday, December 03, 2009 SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'D', 'de') SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'D', 'fr-fr') -- jeudi 3 décembre 2009 SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'dd', '') -- 03 SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'dd-MMM', '') SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'tt', 'ja-jp') -- 午後 SELECT SQL#.Math_IsPrime(12318237133333)
  • #28 Watch the actual execution plan for these statements: drop table dbo.t1 drop table dbo.t2 --create two test tables create table dbo.t1 (c1 int , c2 int check(c2 between 10 and 20)); insert into dbo.t1 values (11,12); create table dbo.t2 (c1 int , c2 int); go insert into dbo.t2 values (101, 102); go select t1.c1 , t2.c2 , t2.c2 from dbo.t1 join dbo.t2 on t1.c1 = t2.c2 and t1.c2 = 20; select t1.c1 , t1.c2 , t2.c2 from dbo.t1 join dbo.t2 on t1.c1 = t2.c2 and t1.c2 = 30;
  • #30 DBCC OPENTRAN select s.plan_handle , t.text , sum(s.execution_count) as totalExecutionCount , sum(s.total_elapsed_time) as totalElapsedTime , sum(s.total_worker_time) as totalWorkerTime , sum(s.total_logical_reads) as totalLogicalReads , sum(s.total_logical_writes) as totalLogicalWrites from sys.dm_exec_query_stats s cross apply sys.dm_exec_sql_text(s.plan_handle) t group by s.plan_handle, t.text order by sum(s.execution_count) desc