I am trying the example given in this blog in my laptop.
https://jonathanlewis.wordpress.com/2013/06/25/system-stats-2/
I get the values the same as mentioned in the blog, but when I use the parallelism hint, the system is not using the DOP, but instead the same old plan is generated. I am not sure what I am missing or what values I did not set.
I have set my parallel_max_servers using the following statement:
alter system set parallel_max_servers=40 scope=both;
When I run the explain statement as:
explain plan for select /*+ parallel(t1 5) */ max(n1) from t1;
I am still getting the same old plan as if no parallelism is used. Is there any other parameter I need to set to make my system use the parallelism.
Thanks!
With the parallel hint, you don't need to specify a table name...just the parallelism quantity. Like this:
select /*+ PARALLEL (4) */ max(n1)
from t1;
I confirmed that adding the table name, prevents parallelism from occurring in the execution plan.
Related
I wanted to know if we can run parallel update/delete/insert on tables which were not created using parallel query.
ex:
Create table Discount(
sales_rep_id number,
discount number,
performance_indicator number
) tablespace commt;
(notice the absence of parallel keyword in the above ddl query)
now can I update the above table with the below parallel hint?
update /*+ PARALLEL(discount) */
Discount set performance_indicator = 50 where discount<30 ;
Yes, parallel DML can run against a table that was created with NOPARALLEL (the default parallel setting).
The table-level setting is only for convenience, for tables that should usually be processed with parallelism. That setting can be over-ridden by a SQL hint.
But the session will need to run this first:
alter session enable parallel dml;
And I recommend you use statement-level parallelism instead of object-level parallelism. This makes everything in the statement run with the same DOP. In general, if one part of the statement uses parallelism, they all should. Simply remove the object name from the query and Oracle will set the DOP for the whole statement:
update /*+ parallel */ discount ...
execute very slowly on below sql statement, env: oracle 9. Please advise the cause or hints to debug. Thanks a lot .
INSERT INTO tmp_table (col1,col2,col3,col4,col5,col6,col7,col8,col9)
select * from my_view where col1 = 1;
How far i tested: execute the select sub-statement cost 3 sec to get 1 record returned while endless executing but no resultset returned when execute the entire statement, like hanging.
When a query appears to execute quickly, in the sense that the last row is returned quickly rather than just the first row, but it runs slowly when used in an insert statement, the usual suspects are:
A change in the execution plan, driven by the optimiser believing that an all_rows goal is now appropriate where previously a first_rows goal was used. Check the execution plan for changes.
Some action being executed as a result of the insert. Slow triggers on the target table, or materialised view logging, are possible causes. This would not be the case when running "create table ... as select ..".
I'm developing Pg/PLSQL function for PostgresQL 9.1. When I use variables in a SQL query, optimizer build a bad execution plan. But if I replace a variable by its value the plan is ok.
For instance:
v_param := 100;
select count(*)
into result
from <some tables>
where <some conditions>
and id = v_param
performed in 3s
and
select count(*)
into result
from <some tables>
where <some conditions>
and id = 100
performed in 300ms
In first case optimizer generate a fixed plan for any value of v_param.
In second case optimizer generate a plan based on specified value and it's significantly more efficient despite not using plan caching.
Is it possible to make optimizer to generate plan without dynamic binding and generate a plan every time when I execute the query?
This has been dramatically improved by Tom Lane in the just-released PostgreSQL 9.2; see What's new in PostgreSQL 9.2 particularly:
Prepared statements used to be optimized once, without any knowledge
of the parameters' values. With 9.2, the planner will use specific
plans regarding to the parameters sent (the query will be planned at
execution), except if the query is executed several times and the
planner decides that the generic plan is not too much more expensive
than the specific plans.
This has been a long-standing and painful wart that's previously required SET enable_... params, the use of wrapper functions using EXECUTE, or other ugly hacks. Now it should "just work".
Upgrade.
For anyone else reading this, you can tell if this problem is biting you because auto_explain plans of parameterised / prepared queries will differ from those you get when you explain the query yourself. To verify, try PREPARE ... SELECT then EXPLAIN EXECUTE and see if you get a different plan to EXPLAIN SELECT.
See also this prior answer.
Dynamic queries doesn't use cached plans - so you can use EXECUTE USING statement in 9.1 and older. 9.2 should to work without this workaround as Craig wrote.
v_param := 100;
EXECUTE 'select count(*) into result from <some tables> where <some conditions>
and id = $1' USING v_param;
Just requesting some clarification on the difference between the 2. From what I understand, EXPLAIN PLAN gives you the theoretical execution plan while DBMS_XPLAN.DISPLAY_CURSOR gives you the actual execution plan with execution statistics for the statement.
EXPLAIN PLAN stores this data in a PLAN_TABLE while DBMS_XPLAN uses the V$SQL_PLAN, V$SQL_PLAN_STATISTICS and V$SQL_PLAN_STATISTICS_ALL views for its information.
However, for DISPLAY_CURSOR to collect the actual runtime statistics for that statment, one needs to set the /*+ gather_plan_statistics */ hint. Otherwise, only V$SQL_PLAN is filled which will only give you the execution plan but not the actual execution statistics. It is only with the /*+ gather_plan_statistics */ where V$SQL_PLAN_STATISTICS is filled.
So my question is, if I do not use the gather_plan_statistics hint, will EXPLAIN PLAN and DISPLAY_CURSOR always give me the same execution plan (for the same statement)?
The differences are not very subtle, they are huge.
As you correctly mentioned, explain plan stores it's data in the plan_table and the plan is queried from that table. This means that the sql is NOT executed, only the optimizer is asked to deliver a plan. In that setup the plan depends heavily on the optimizer environment of your session in which you run the explain plan.
With DBMS_XPLAN.DISPLAY_CURSOR you get the plan as it has been executed before. The plan is not stored by issuing the DBMS_XPLAN.DISPLAY_CURSOR; it stored in the v$ structures because it has been executed.
In a session you can run
select * from dual;
select * from table(dbms_xplan.display_cursor);
The query is executed in the 'select from dual', this also results in the creation of a plan and that i stored in the v$ structures. the display_cursor just finds the last executed cursor and displays the plan it followed. With this setup /*+ gather_plan_statistics */ has no added value because the plan and it's statistics are already present in the shared_pool.
Your other question, whether or not the plan is always the same depends on many factors. Are the variables the same?, are you using Adaptive Cursor Sharing, are you using SQL Plan Stability ...
Your question: give explain plan and display_cursor the same plan? I would not rely on that because with explain plan, the plan depends from your sessions optimizer environment. display_cursor is the better way, and preferably using a named cursor that is created by the application. If you don't use SQL Plan Stability, the plan can change when the optimizer statistics change. If you use Adaptive Cursor Sharing, the plan can change when the variables change.
A bit of nice reading about the overhead of the sampling can be found at Jonathan Lewis blog. Also from Jonathan: gather_plan_statistics I is often smarter to use statistics_level setting 'all' for debugging as opposed to using the /*+ gather_plan_statistics */ hint. The hint changes code and causes a new sql_id.
I hope this helps.
Does sql server cache the execution plan of functions?
Yes, see rexem's Tibor link and Andrew's answer.
However... a simple table value function is unnested/expanded into the outer query anyway. Like a view. And my answer (with links) here
That is, this type:
CREATE FUNC dbo.Foo ()
RETURNS TABLE
AS
RETURN (SELECT ...)
GO
According to the dmv yes, http://msdn.microsoft.com/en-us/library/ms189747.aspx but I'd have to run a test to confirm.
Object ID in the output is "ID of the object (for example, stored procedure or user-defined function) for this query plan".
Tested it and yes it does look like they are getting a separate plan cache entry.
Test Script:
create function foo (#a int)
returns int
as
begin
return #a
end
The most basic of functions created.
-- clear out the plan cache
dbcc freeproccache
dbcc dropcleanbuffers
go
-- use the function
select dbo.foo(5)
go
-- inspect the plan cache
select * from sys.dm_exec_cached_plans
go
The plan cache then has 4 entries, the one listed as objtype = Proc is the function plan cache, grab the handle and crack it open.
select * from sys.dm_exec_query_plan(<insertplanhandlehere>)
The first adhoc on my test was the actual query, the 2nd ad-hoc was the query asking for the plan cache. So it definitely received a separate entry under a different proc type to the adhoc query being issued. The plan handle was also different, and when extracted using the plan handle it provides an object id back to the original function, whilst an adhoc query provides no object ID.