I recently was trying to understand Oracle's data dictionary tables and I noticed something rather strange.
When I run a query like
select * from table where id in (?, ?);
just once, I notice that there are 2 rows created in v$sql for the same query. why is that?
However, if i run something like
select * from table where id = 10;
I see only a single row being created.
Related
I created a table in oracle like
CREATE TABLE suppliers AS (SELECT * FROM companies WHERE id > 1000);
I would like to know the complete select statement which was used to create this table.
I have already tried get_ddl but it is not giving the select statement. Can you please let me know how to get the select statement?
If you're lucky one of these statements will show the DDL used to generate the table:
select *
from gv$sql
where lower(sql_fulltext) like '%create table suppliers%';
select *
from dba_hist_sqltext
where lower(sql_text) like '%create table%';
I used the word lucky because GV$SQL will usually only have results for a few hours or days, until the data is purged from the shared pool. DBA_HIST_SQLTEXT will only help if you have AWR enabled, the statement was run in the last X days that AWR is configured to hold data (the default is 8), the statement was run after the last snapshot collection (by default it happens every hour), and the statement ran long enough for AWR to think it's worth saving.
And for each table Oracle does not always store the full SQL. For security reasons, DDL statements are often truncated in the data dictionary. Don't be surprised if the text suddenly cuts off after the first N characters.
And depending on how the SQL is called the case and space may be different. Use lower and lots of wildcards to increase the chance of finding the statement.
TRY THIS:
select distinct table_name
from
all_tab_columns where column_name in
(
select column_name from
all_tab_columns
where table_name ='SUPPLIERS'
)
you can find table which created from table
I have a database that has say 100 other_users.
I am logged in as the database owner and I want to query a specific table in all the other users schemas.
So let's say each schema has a table called propertyvalue.
I want to find out which schemas have this value set to TRUE.
Is there a way I can run a select statement against all the other users schemas without specifically pointing to an individual schema.
Something like:
select * from otherusers.propertyvalue where value = 'TRUE', which doesn't work as I have tried that.
Thanks.
You can write a statement that will write select statements to do this
SELECT 'SELECT '||owner||'.'||table_name||'.'||column_name ||
' FROM '||owner||'.'||table_name||';'
FROM All_Tab_Cols atc
WHERE atc.column_name = 'PROPERTYVALUE';
Run this statement as a user with select privilege on the table and then run the selects that are the output.
However tables with multiple rows will return all rows. Are you expecting that there is only one row in each table?
You could also write an anonymous block that will open a cursor with the same statement and output the results to a file/table/output.
SELECT * FROM (
select *
from tableA
where ColumnA = 'randomText'
ORDER BY columnL ASC
) WHERE ROWNUM <= 25
on execution of this query, due to some Oracle optimization, the query takes about 14 minutes to execute . If I remove the where clause , the query executes in seconds. most of the columns of the table have indexes on them, including the ones mentioned above. I do not have much flexibility on the structure of the query as I use hibernate.
This query returns results instantly too, with the correct result:
SELECT *
FROM (
select *
from tableA,
dual
where ColumnA = 'randomText'
ORDER BY columnL ASC
) WHERE ROWNUM <= 25
is there something I can do, using hibernate?
UPDATE: I use EntityManager.createQuery(), and I use setMaxResults(25) and setFirstResult() too. the query above is what hibernate's query looks like, upon observation of logs
I don't get the explain plans exactly matched to your queries, but it seems oracle using a different index for the two queries.
Can you create an index containing columnA and columnL?
If you have an index only containing columnA, you MIGHT be able to drop that without a large effect on performance of other queries.
An alternative would be to add a hint to use the index used in the faster query. But this would require you to use native sql.
this means you are using hibernate/jpa? If so, I guess you are using the EntityManager.createNativeQuery() to create the query? Try removing your where-restriction and use the .setMaxResults(25) on the Query instead.
Anyways, why do you need the outer-select? Wouldn't
select *
from tableA
where ColumnA = 'randomText'
AND ROWNUM <= 25
ORDER BY columnL ASC
produce the desired results?
SELECT object_id from dbname.tablename
This query has to be executed against oracle 11g.I get errors when i execute this.
I do a migration from sybase to oracle and in oracle this query fails.
What could be the problem. Please suggest a solution
"What could be the problem."
All sorts of things. Since you failed to state what errors you're getting, we can only guess, e.g.:
Table not found
No SELECT privilege on table
dbname not a valid schema
object_id not a column in the table
Not connected to a running oracle instance
Trying to run the statement in an environment that doesn't understand SQL
etc, etc, ...
If all you want is to check that the table exists, you could do this:
SELECT 1 FROM dba_tables WHERE owner = 'DBNAME' AND table_name = 'TABLENAME';
If you want to check that you can query the table, you could do this:
SELECT 1 FROM schemaname.tablename WHERE 1=0;
If you want to check if the table has any rows, you could do this:
SELECT 1 FROM schemaname.tablename WHERE ROWNUM <= 1;
What you will do with the result. If you only want a unique id for a row, yo can user SELECT ROWID FROM dbname.tablename!
I have a view that is very slow if you fetch all rows. But if I select a subset (providing an ID in the where clause) the performance is very good. I cannot hardcode the ID so I create a sub select to get the ID from another table. The sub select only returns one ID. Now the performance is very slow and it seems like Oracle is evaluating the whole view before using the where clause. Can I somehow help Oracle so SQL 2 and 3 have the same performance? I’m using Oracle 10g
1 slow
select * from ci.my_slow_view
2 fast
select * from ci.my_slow_view where id = 1;
3 slow
select * from ci.my_slow_view where id in (select id from active_ids)
How about
select * from ci.my_slow_view where id = (select id from active_ids)
Replacing the "in" with an "=" will tell Oracle that you expect the "select id from active_ids" to return only a single row.
This is the expected behavior...
3 is slow because Oracle will perform a "full table scan", which means that your indexes are not helping there (your where clause does not contain any constant or range and is unbounded, which implies that whatever index you use, all the rows are potentially candidates for the join condition.
Possible improvment:
First, check that the indexes are ok on your join/pk columns (id in my_slow_view and active_ids). This is necessary for the second step:
Second, generate table statistics for your table and views, that will make the Oracle cache memory optimizer kicks in.
(It should work because it is assumed that your active_ids table is small enough to be fully in memory.)
Second approach:
Write a stored procedure in PL/SQL where your id is an in parameter and rewrite your SQL so that it is used a bound parameter.
That should give you the flexibility you need (no hard coded ids), and the speed of the fastest query.
I cannot hardcode the ID so I create a
sub select to get the ID from another
table. The sub select only returns one
ID.
Most likely, gathering statistics on the small table (while it contains a single row) will help, since that should help Oracle realize that it is small and encourage it to use the index on ID.
However, it sounds like this is really not the right solution to your original problem. Generally, when one wants to perform a query repeatedly with a different lookup value, the best way is to use a bind variable. The basic method of doing this in SQLPlus would be:
SQL> variable id number
SQL> exec :id := 1;
SQL> select * from ci.my_slow_view where id = :id ;
SQL> exec :id := 2;
SQL> select * from ci.my_slow_view where id = :id ;
The details of implementing this depend on the environment you are developing in.
Or:
select * from ci.my_slow_view, active_ids
where my_slow_view.id = active_ids.id;