Oracle DDL statment ( like CTAS) , after executed, not show in V$SQL - sql

Why Oracle "DDL" statements (like "CTAS"), after executed, does not shown in V$SQL view ?
How can get "SQL_ID" of that? I want to use "SQL_ID" in SQl plan baselines. TNX

V$SQL shows just the first 20 charachter for CTAS. It is a bug in Oracle Database 11g. For more details, see: (https://stackoverflow.com/questions/27623646/oracle-sql-text-truncated-to-20-characters-for-create-alter-grant-statements/28087571#28087571\)1.

CTAS operations appear in the v$sql view
SQL> create table t1 as select * from dba_objects ;
Table created.
SQL> select sql_text,sql_id from v$sql where sql_text like '%create table t1 as select%' ;
SQL_TEXT
--------------------------------------------------------------------------------
SQL_ID
-------------
create table t1 as select * from dba_objects
4j5kv6x7cz5r7
select sql_text,sql_id from v$sql where sql_text like '%create table t1 as selec
t%'
5n4xnjkt3vz3h
SQL Plan Baselines are part of SPM ( SQL Plan Management )
A SQL plan baseline. A plan baseline is a set of accepted plans that
the optimizer is allowed to use for a SQL statement. In the typical
use case, the database accepts a plan into the plan baseline only
after verifying that the plan performs well. In this context, a plan
includes all plan-related information (for example, SQL plan
identifier, set of hints, bind values, and optimizer environment) that
the optimizer needs to reproduce an execution plan.
If you are using a CTAS recurrently, I guess you are doing it in batch mode, thus dropping the table and then recreate it afterwards using the mentioned CTAS command. I would rather try to see what is the problem with the SELECT itself of that statement.
But SQL Baselines are more focus for solving queries which plans can be fixed and evolved as the optimizer is not always choosing the best one.

Related

Missing index details for procedure in SQL Server

I have stored procedure having two select statement combined with union all operator. Each select statement contains five left joins with views. The select performance is very slow. Each table contains 10 million records.
Is there any way (query or any other method) to find missing index details for the stored procedure?
Missing index details, if any, are included in the stored procedure execution plan. The actual or estimated plan can be viewed from SSMS (Query menu options) or retrieved from cache using the query below.
SELECT query_plan
FROM sys.dm_exec_procedure_stats AS ps
CROSS APPLY sys.dm_exec_query_plan(ps.plan_handle)
WHERE object_id = OBJECT_ID(N'YourDatabase.dbo.YourProcedure');

Oracle EXPLAIN PLAN FOR Returns Nothing

I run the following query on an Oracle database:
EXPLAIN PLAN FOR
SELECT *
FROM table_name
However, it's not returning any data. When I delete the EXPLAIN PLAN FOR clause, the query does run as expected. Thanks for the help!
In case it's relevant, I'm accessing the database through Teradata and also a Jupyter IPython notebook.
From Using EXPLAIN PLAN:
The PLAN_TABLE is automatically created as a global temporary table to hold the output of an EXPLAIN PLAN statement for all users. PLAN_TABLE is the default sample output table into which the EXPLAIN PLAN statement inserts rows describing execution plans
EXPLAIN PLAN FOR SELECT last_name FROM employees;
This explains the plan into the PLAN_TABLE table. You can then select the execution plan from PLAN_TABLE.
Displaying PLAN_TABLE Output
UTLXPLS.SQL
UTLXPLP.SQL
DBMS_XPLAN.DISPLAY table function
I suggest to use:
EXPLAIN PLAN FOR SELECT * FROM table_name;
SELECT * FROM TABLE(dbms_xplan.display);

Hive Query Efficiency

Could you help me with a Hive Query Efficiency problem? I have two queries working for the same problem. I just cannot figure out why one is much faster than the other. If you know please feel free to provide insight. Any info is welcomed!
Problem: I am trying to check the minimum value of a bunch of variables in a Hive parquet table.
Queries: I tried two two queries as follows:
query 1
drop table if exists tb_1 purge;
create table if not exists tb_1 as
select 'v1' as name, min(v1) as min_value from src_tb union all
select 'v2' as name, min(v2) as min_value from src_tb union all
select 'v3' as name, min(v3) as min_value from src_tb union all
...
select 'v200' as name, min(v200) as min_value from src_tb
;
query 2
drop table if exists tb_2 purge;
create table if not exists tb_2 as
select min(v1) as min_v1
, min(v2) as min_v2
, min(v3) as min_v3
...
, min(v200) as min_v200
from src_tb
;
Result: Query 2 is much faster than query 1. It took probably 5 mins to finish the second query. I don't know how long will query 1 take. But after I submit the first query, it took a long time to even react to the query, by which I mean that usually after I submit a query, the system will start to analyze and provides some compiling information in the terminal. However, for my first query, after my submission, the system won't even react to this. So I just killed it.
What do you think? Thank you in advance.
Query execution time depends on environment that you execute it.
In MSSQL.
Some people like you think query execution is similar to algorithm that they see in some theoretical resources, but in practical situation, it depends on other things.
For example both of your queries have SELECT statement that perform on a table and at first glance, they need to read all rows, but database server must analyze the statement to determine the most efficient way to extract the requested data. This is referred to as optimizing the SELECT statement. The component that does this is called the Query Optimizer. The input to the Query Optimizer consists of the query, the database schema (table and index definitions), and the database statistics. The output of the Query Optimizer is a query execution plan, sometimes referred to as a query plan or just a plan. (Please see this for more information about query-processing architecture)
You can see execution plan in MSSQL by reading this article and I think you will understand better by seeing execution plan for both of your queries.
Edit (Hive)
Hive provides an EXPLAIN command that shows the execution plan for a query. The syntax for this statement is as follows:
EXPLAIN [EXTENDED|DEPENDENCY|AUTHORIZATION] query
A Hive query gets converted into a sequence of stages. The description of the stages itself shows a sequence of operators with the metadata associated with the operators.
Please see LanguageManual Explain for more information.
What is surprising? The first query has to read src_tb a total of 200 times. The second reads the data once and performs 200 aggregations. It is a no brainer that it is faster.

How to reliably get the SQL_ID of a query

I know this might seem a simple question - for which you might think existing answers exist. However ...
Understand that I want it be reasonable in performance, so it allows to be logged for every single query executed - or at least the big ones - without much overhead.
My first idea was this query:
select sid,serial#,prev_sql_id from v$session where audsid=userenv('sessionid');
My idea was if I run this right after my target query, I will capture the correct sql_id through prev_sql_id.
However ... I was not ... I was getting a different SQL ... apparently in between my target SELECT statement and the query for prev_sql_id, something else ran. In my case Auditing is enabled, and I was capturing the insert into the SYS.AUD$ table. No good.
As my main purpose for this attempt was to capture the execution plan for the query (as it was executed and captured by the shared pool), I thought that instead I can simply run this query:
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
Documentation states that with NULL SQL_ID as parameter, it will run the explain plan on the most recent query ran. I was hoping that this would take care of earlier issues. However ... I got the plan for the exact same insert into the SYS.AUD$ table.
You might say, ok, then just simply put a comment in your query that allows to easily capture the SQL_ID, like in following:
SELECT /* SQL: 1234-12' */ FROM DUAL;
Then I can try to find the SQL_ID as follows:
SELECT * FROM V$SQLAREA WHERE sql_text like '%SQL: 1234-12%';
That will give me several possible candidates, of which the V$SQLAREA query itself is also included. The problem here is that I will need to randomize every query ran, which would cause me to always have a hard-parse.
I have tried other solutions where I go through history, but that comes at a much bigger cost. I have tried to search other solutions. They all seem to lag in some way.
Related Articles:
Blog: Displaying and Reading the exception plans for a SQL Statement
Oracle queries executed by a session
You could use new SQL*Plus option:
SET FEEDBACK ON SQL_ID;
SQL_ID returns the sql_id for the SQL or PL/SQL statements that are executed. The sql_id will be assigned to the predefined variable _SQL_ID. You can use this predefined variable to debug the SQL statement that was executed. The variable can be used like any other predefined variable, such as _USER and _DATE.
SQL> SET FEEDBACK ON SQL_ID
SQL> SELECT * FROM DUAL;
D
-
X
1 row selected.
SQL_ID: a5ks9fhw2v9s1
--
SQL> SELECT sql_text FROM v$sql WHERE sql_id = '&_sql_id';
SQL_TEXT
-----------------------------------------------------
SELECT * FROM DUAL
1 row selected.

Oracle query over db link loses index and performs full table scan

I have a query that has a good execution plan...
When I take this query and run it over a database link I lose the index in the execution plan...
Is there any way to get this query to keep the index?
regards
Your query has to be this way only,
SELECT /*+ DRIVING_SITE(thead) */ *
FROM thead#ORPMYRP.CMLTD.NET.AU
WHERE business_part_date=trunk(sysdate)
and processed_ind='N';
OR use a Global hint like below, when subquery is in place.
SELECT /*+ DRIVING_SITE(a.thead) */ *
FROM
(SELECT * FROM thead#ORPMYRP.CMLTD.NET.AU
WHERE business_part_date=trunk(sysdate)
and processed_ind='N') a
When you use like below,
SELECT /*+ DRIVING_SITE(a) */ *
FROM
(SELECT * FROM thead#ORPMYRP.CMLTD.NET.AU
WHERE business_part_date=trunk(sysdate)
and processed_ind='N') a
The hint gets useless as the alias name a is no more meaningful to be useful in HINT as it doesnt refer a table but a subquery's result. And entire rows of AU table in remote db is sent to the local now. So it means, index is of no use now, so oracle goes for full table scan.