I'm running some top-line stats for our Oracle database, to report a count of the total number of Tables. I'm using some very basic SQL queries against the db views: TABLES and TAB_COLUMNS
When comparing a count of the number of records in the DBA_TABLES view, with a count of the number of distinct Owner/Table_Name combinations in the the DBA_TAB_COLUMNS, I've found that there are significantly more tables listed in the TAB_COLUMNS view (a total of 12,508, in my case), than in the TABLES view (a total of 6,630).
Looking at a data-level sample of the disparities, these 'extra' tables showing in the TAB_COLUMNS all appear to contain no rows of data.
Clearly, a chat with my DBA to understand why so many empty tables is my next port of call (could be a number of reasons I'm sure) - but my question is: how come the TABLES view apparently excludes these tables, when the TAB_COLUMNS view includes them?
There's that useful dictionary thing which contains interesting info. For example:
SQL> select * from dictionary where table_name in ('USER_TAB_COLUMNS', 'USER_TABLES');
TABLE_NAME COMMENTS
------------------------------ --------------------------------------------------
USER_TABLES Description of the user's own relational tables
USER_TAB_COLUMNS Columns of user's tables, views and clusters
SQL>
As user_tab_columns contains tables and views and clusters, I guess that's the reason your queries returned different results. Try to remove what you don't need.
How? One option is to JOIN these two. Another is to switch to USER_OBJECTS whose object_type column says what is what.
Related
i have a slow query whose structure is
select
fields
from
table
join
manytables
join (select fields from tables) as V1 on V1 on V1.field = ....
join (select fields1 from othertables) as V2
join (select fields2 from moretables) as V3
The select subqueries in the last 3 joins are relatively simple but joins agains the, take time. If they were phisical tables it would be much better.
So i found out that i could turn the subqueries to indexed views or to temp tables.
By temp table i do not mean a table who is written hourly like explained here,
but a temp table who is created before the query execution
Now my doubt comes from the fact that indexed views are ok in datawarehouses since they impact the performance. This db is not a datawarehouse but a production db of a non data intense application.
But in my case the above query is executed not often, even if the underlaying tables (the tables whose data would become part of the indexed view) are used more often.
In this case is it ok to use indexed views? Or shuold i favor temp table?
Also table variable with primary key keyword is an alternative.
How to compare table data structure.
1. Any table added or deleted.
2. Any column in the tables added or deleted.
So my job is to verify if any table or columns are added/deleted on 1st of every month.
My plan is to run a sql query and take a copy of entire list of tables and it's data type only (NO DATA) and save it in txt file or something and use it as base line, and next month run the same sql query and get the results and compare the file. is it possible? please help with the sql query which can do this job.
This query will give you a list of all tables and their columns for a given user (just replace ABCD in this query for the user you have to audit and providing you have access to all that users tables this will work).
SELECT table_name,
column_name
FROM all_tab_columns
WHERE owner = 'ABCD'
ORDER
BY table_name,
column_id;
This answers your question but I have to agree with a_horse_with_no_name that is not a good way implement change control, most notably because the changes have already happened.
This query is very basic and doesn't give you all the information you'd need to see if a column has changed (or any information about other objects types etc), but then you only asked about additions and deletions of tables and columns and you can compare the output of this script to previous outputs to find the answer to your allotted task.
I'm looking for a query allowing me to query all the tables, views, JOBS, and PROCEDURES in the oracle database. I've found some links to queries that will work for the tables and views but I need jobs and procedures. If one query can't be used for all this, I need at least job and procedures.
Here is what I found for the tables and views:
Select TABLE_NAME, COLUMN_NAME from user_tab_columns
TIA
My guess is that you want something like
SELECT name, type, line, text
FROM user_source
WHERE lower(text) like lower('%<<column name>>%');
That will show you any line of code in any pL/SQL object (package, package body, procedure, function, trigger, type, etc.) that contains the column name. If there are multiple tables with identically named columns (i.e. a column name is found in many different tables), all instances will be identified. There isn't a really great way, short of inspecting the code, to figure out which queries refer the name column in one particular table. You could potentially look to see whether the NAME and TYPE from USER_SOURCE appear in DBA_DEPENDENCIES as referencing the particular table you're interested in. But that just shows you table-level dependencies at an object level and your object may depend on a large number of different tables.
I have over million records in these tables in both the databases.
I am trying to figure out data in both the tables acros databases.
SELECT COUNT(*) FROM DB1.MYTABLE WHERE SEQ_NO NOT IN(SELECT SEQ_NO FROM DB2.MYTABLE) AND FILENAME NOT LIKE '%{%'
and PT_TYPE NOT IN(15,24,268,284,285,286,12,17,9,290,214,73) AND STTS=1
The query is taking ages. Is there any way I can make it fast?
Appreciate your help in advance
Do you actually mean different databases? Or do you mean different schemas? You talk about different databases but the syntax appears to be using tables in two different schemas, not two different databases. I don't see any references to a database link which would be needed if there were two different databases but perhaps DB2.MYTABLE is supposed to be a synonym for MYTABLE#DB2.
It would be helpful if you could post the query plan that is generated. It would also be useful to indicate what indexes exist and how selective each of these predicates is. My guess is that modifying the query to be
SELECT count(*)
FROM schema1.mytable a
WHERE NOT EXISTS (
SELECT 1
FROM schema2.mytable b
WHERE a.seq_no = b.seq_no )
AND a.filename NOT LIKE '%{%'
AND a.pt_type NOT IN (15,24,268,284,285,286,12,17,9,290,214,73)
AND a.stts = 1
might be more efficient if most of the rows in SCHEMA1.MYTABLE are eliminated because the SEQ_NO exists in SCHEMA2.MYTABLE.
How can I determine if an Oracle index is clustered or unclustered?
I've done
select FIELD from TABLE where rownum <100
where FIELD is the field on which is built the index. I have ordered tuples, but the result is wrong because the index is unclustered.
By default all indexes in Oracle are unclustered. The only clustered indexes in Oracle are the Index-Organized tables (IOT) primary key indexes.
You can determine if a table is an IOT by looking at the IOT_TYPE column in the ALL_TABLES view (its primary key could be determined by querying the ALL_CONSTRAINTS and ALL_CONS_COLUMNS views).
Here are some reasons why your query might return ordered rows:
Your table is index-organized and FIELD is the leading part of its primary key.
Your table is heap-organized but the rows are by chance ordered by FIELD, this happens sometimes on an incrementing identity column.
Case 2 will return sorted rows only by chance. The order of the inserts is not guaranteed, furthermore Oracle is free to reuse old blocks if some happen to have available space in the future, disrupting the fragile ordering.
Case 1 will most of the time return ordered rows, however you shouldn't rely on it since the order of the rows returned depends upon the algorithm of the access path which may change in the future (or if you change DB parameter, especially parallelism).
In both case if you want ordered rows you should supply an ORDER BY clause:
SELECT field
FROM (SELECT field
FROM TABLE
ORDER BY field)
WHERE rownum <= 100;
There is no concept of a "clustered index" in Oracle as in SQL Server and Sybase. There is an Index-Organized Table, which is similar but not the same.
"Clustered" indices, as implemented in Sybase, MS SQL Server and possibly others, where rows are physically stored in the order of the indexed column(s) don't exist as such in Oracle. "Cluster" has a different meaning in Oracle, relating, I believe, to the way blocks and tables are organized.
Oracle does have "Index Organized Tables", which are physically equivalent, but they're used much less frequently because the query optimizer works differently.
The closest I can get to an answer to the identification question is to try something like this:
SELECT IOT_TYPE FROM user_tables
WHERE table_name = '<your table name>'
My 10g instance reports IOT or null accordingly.
Index Organized Tables have to be organized on the primary key. Where the primary key is a sequence generated value this is often useless or even counter-productive (because simultaneous inserts get into conflict for the same block).
Single table clusters can be used to group data with the same column value in the same database block(s). But they are not ordered.