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)
Showing posts with label ExecutionPlan. Show all posts
Showing posts with label ExecutionPlan. Show all posts

PostgreSQL - EXPLAIN - Show execution plan

EXPLAIN
Display the execution plan which PostgreSQL generates.
EXPLAIN ANALYZE
Display more statistics. Display actual run-time statistics.



In order to analyze INSERT, UPDATE, DELETE without affecting the data – run EXPLAIN ANALYZE in a transaction:
BEGIN;
    EXPLAIN ANALYZE sql_statement;
ROLLBACK;

Get plans of a Stored Procedure

Select  PS.total_logical_reads/NullIf(DateDiff(Minute,PS.cached_time,GetDate()),0) N,
        Coalesce(DB_Name(PS.database_id),DB_Name(PSh.dbid),DB_Name(PSph.dbid))
        DBName,
        Object_Schema_Name(Coalesce(PS.object_id,PSh.objectid,PSph.objectid),Coalesce(PS.database_id,PSh.dbid,PSph.dbid))
        SchemaName,
        Coalesce(Object_Name(PS.object_id,PS.database_id),Object_Name(PSh.objectid,PSh.dbid),Object_Name(PSph.objectid,PSph.dbid))
        ObjectName,
        PS.*,
        PSh.text,
        PSph.query_plan
From    (Select Object_Name(object_id), *
        From    sys.dm_exec_procedure_stats (NoLock)
        Where   database_id=DB_ID('DatabaseName')
                And Object_Schema_Name(object_id)='SchemaName'
                And Object_Name(object_id)='SpName'
        Order By total_logical_reads/NullIf(DateDiff(Minute,cached_time,GetDate()),0) Desc) PS
Outer Apply sys.dm_exec_sql_text(PS.sql_handle) PSh
Outer Apply sys.dm_exec_query_plan(PS.plan_handle) PSph;

Actual very different than estimated - what to do in the first step!

You run a query / stored procedure, etc. and - bad performance... The you also see that the actual very different than estimated data in the execution plan.

There are 1,000,000 things to think about, 1,000,000 blogs posts about reasons, actions and so on about such a case.

BUT:
First of all, in those scenarios - before all the complicated things:
  • Check the logic that behind the query, 
  • Check that this logic is implemented in the query,
  • Check that the tables order and joins is acording to the DB structure and logic.
See that the query is written as you would expect according to the database and/or the application logic.

After that - in most of the cases - 90% of the work will be done!


SentryOne Plan Explorer PRO Goes FREE!

SentryOne Plan Explorer is one of the best tool that help to investigate execution plans on SQL Server.

Now it's free!

Output list - Lookup columns

In order to see the columns we get from the lookup operation:

Right click on the lookup icon in the execution plan --> Output list


Costs are estimated, lines thickness is actual

This one is important and confusing:
costs are estimated, lines thickness is actual!

SQL Sentry Plan Explorer

SQL Sentry Plan Explorer (sqlSentry) is a FREE tool that builds upon the graphical plan view in SQL Server Management Studio to make query plan analysis more efficient.

It is a Recommended tool to more comfortable view and for better understand of execution plans:
  • You can see the relevant icons on the execution plan by sign a part of the query.
  • You can see lists of top operations by costs and more, and move from an operation in the table to the plan.
  • You have few views of the execution plan: diagram, XML, etc.
  • And more...





Performance statistics for cached query plans

SELECT
DB_NAME(st.[dbid]) AS DBName,
OBJECT_NAME(st.objectid, st.[dbid]) as ObjectName,
qs.plan_generation_num,
qs.execution_count,
( SUBSTRING(st.[text], (qs.statement_start_offset/2) + 1,
 ((CASE qs.statement_end_offset 
 WHEN -1 THEN DATALENGTH(st.[text])
 ELSE qs.statement_end_offset END 
 - qs.statement_start_offset)/2) + 1)
) AS statement_text
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS st
WHERE DB_NAME(st.[dbid]) = 'DataBaseName' 
AND OBJECT_NAME(st.objectid, st.[dbid]) = 'ObjectName'

plan_generation_num - number of plan generation for this Object
execution_count - number of executions of the current plan

if plan_generation_num is more than 1 and execution_count 1:
new plan is generated for each execution --> probably not a good situation.
if plan_generation_num is 1 and execution_count is big:
probably good situation.

Some basic and important Execution Plan rules

  • Read from Right To Left and Top to Bottom.
  • Read it from right to left, as data flow comes from right to left side.
  • If you see nested loop, the upper side is the outer query, the lower side is inner query, inner query is executed once for each outer query.
  • Follow Arrows until next branch from below.
  • The thickness of the arrow reflects the amount of data being passed.
  • execution cost of inner side for nested loop is per execution of outer side.
  • If you see hash join, it means that hash table is built for upper (outer) query, then for each rows in lower (inner) query, query processor will look into the hash table to find match value.
  • The number that displayed as a precentage is the relative cost to the query for the operator.

  • Table Scan - scan all the rows of the table in order to select the results set.
  • Index Scan - scan all the rows of the indexed table in order to select the results set. We will scan indexed table when all of the table rows, or the most of them will be returned.
  • Index Scan - Seek the table, using indexes, in order to select the results set.
  • In the most of the cases, seek is better than scan.