Run DB2 Runstats without activity but still get SQLSTATE=01650 - sql

After reading many of articles from the internet, I am still not sure what is the actual purpose of DB2 Runstats.
As my understanding, DB2 Runstats will "register" the table index to the DB2 catalog, so that next time when the related query run, it will use the index to increase the performance. (Please correct me if I am wrong)
Meaning, if for a long period of time the DB2 Runstats is not run, the index will be removed from the DB2 catalog?
I am creating a new index for a table. Originally that table already contained another index.
After creating the new index, I ran DB2 Runstats on the table for the old index, but I hit the following error:
SQL2314W Some statistics are in an inconsistent state. The newly collected
"INDEX" statistics are inconsistent with the existing "TABLE" statistics. SQLSTATE=01650
At first I was thinking it's cause by the activity to create the new index, and the table was still in the "processing" stage. I ran the DB2 Runstats command again the next day but still got the same error.

Your understanding about db2 runstats is not correct. This command collects statistics on the given table and its indexes and placed it to views in the SYSSTAT schema like SYSSTAT.TABLES, SYSSTAT.INDEXES, etc. This information is used by the DB2 optimizer to produce better access plans of your queries. It doesn't "register" indexes itself. Indexes are not removed automatically if you don't collect statistics on them.
As for the warning message SQL2314W.
It's just a warning that table and index statistics is not logically compatible (for example, number of index keys is more than number of rows in the table). Sometimes it happens when you collect statistics on actively updated table at the same time even you run such a collection on a table and its indexes using a single RUNSTATS command. You can either ignore this message or make the RUNSTATS utility lock the table during the statistics collection on table and its indexes using a single command (ALLOW READ ACCESS clause).

Related

If the statistics are gathered for a table in oracle database when its empty , then what is the way to restore the original statistics for the table?

The table in question here works in the following way:
Lets consider the table in question here is table A and there are another two tables B and C.
Table C receives first receives all the data from external system.
Data then gets transferred to table B where it is meant to be processed and a copy of that data also get created in table A.As the data continues to process in table B, the status of the data changes in both A and B. Once all the data gets processed in table B, tables gets deleted from table A.
So basically table A queues up the data which is to be processed by table B.
Somehow statistics got gathered in the table A when it was empty although table A at a specific time holds thousands of records.
Hence the sample size of the table became zero. Is there any way the original statistics can be restored in the table.
Read in the oracle site that the restore procedure of dbms_stats package is helpful in restoring the original statistics. But is there any other way of doing it? And will the restoration of statistics helpful in reviving the performance of processing?
The simplest way to proceed seem to just recompute the statistics whenever you need fresh ones. Of course, this is relevant only if stats computation is not too long.
Else, the RESTORE_TABLE_STATS Procedure is probably the simplest way to go:
This procedure restores statistics of a table as of a specified timestamp (as_of_timestamp). The procedure will restore statistics of associated indexes and columns as well.
Consider:
exec dbms_stats.restore_table_stats(
ownname => 'myschema',
tabname => 'mytable',
as_of_timestamp => 'mytimestamp'
);
Finally, another option would be to manually export/import the statistics, following these steps:
create the table statistics using the CREATE_STAT_TABLE Procedure
export the statistics at the relevant moment, using EXPORT_TABLE_STATS
when needed, reimport the stats using IMPORT_TABLE_STATS
This blog link provides a detailed example on how to proceed.
In addition to regathering stats and restoring stats, as suggested by GMB, you might also want to lock the table's statistics. Locking stats can prevent bad stats from happening in the first place.
Run code like this to lock the stats:
begin
dbms_stats.lock_table_stats
(
ownname => 'SOME_USER',
tabname => 'SOME_TABLE'
);
end;
/
That table will be excluded from automatic statistics gathering processes. If a process tries to gather stats manually, without first unlocking the table, it will raise the error "ORA-20005: object statistics are locked (stattype = ALL)".

Are temporary tables in postgresql visible over all client sessions?

I want to create a temp table so as to be able to join it to a few tables because joining those tables with the content of the proposed temporary table takes a lot of time (fetching the content of the temporary table is time consuming.Repeating it over and over takes more and more time). I am dropping the temporary table when my needs are accomplished.
I want to know if these temporary tables would be visible over other client session(my requirement is to make them visible only for current client session). I am using postgresql. It would be great if you could suggest better alternatives to the solution I am thinking of.
PostgreSQL then is the database for you. Temporary tables done better than the standard. From the docs,
Although the syntax of CREATE TEMPORARY TABLE resembles that of the SQL standard, the effect is not the same. In the standard, temporary tables are defined just once and automatically exist (starting with empty contents) in every session that needs them. PostgreSQL instead requires each session to issue its own CREATE TEMPORARY TABLE command for each temporary table to be used. This allows different sessions to use the same temporary table name for different purposes, whereas the standard's approach constrains all instances of a given temporary table name to have the same table structure.
Pleas read the documentation.
Temporary tables are only visible in the current session and are automatically dropped when the database session ends.
If you specify ON COMMIT, the temporary table will automatically be dropped at the end of the current transaction.
If you need good table statistics on a temporary table, you have to call ANALYZE explicitly, as these statistics are not collected automatically.
By default , temporary tables are visible for current session only and temporary tables are dropped automatically after commit or closing that transaction, so you don't need to drop explicitly.
The auto vacuum daemon cannot access and therefore cannot vacuum or analyze temporary tables. For this reason, appropriate vacuum and analyze operations should be performed via session SQL commands. For example, if a temporary table is going to be used in complex queries, it is wise to run ANALYZE on the temporary table after it is populated.
Optionally, GLOBAL or LOCAL can be written before TEMPORARY or TEMP. This presently makes no difference in PostgreSQL and is deprecated

Is gathering statistics necessary after dropping indexes and recreating them?

I use Oracle SQL, and I have one question. I have a table with indexes and it's statistics are gathered. I have a procedure that drops the indexes, inserts data into the table, and after that recreates the same indexes again. Do I need to gather statistics again after this procedure, or will the indexes be recognized anyway?
For gathering statistics i use:
EXEC dbms_stats.gather_table_stats(''MIGBUFFER'','''||table_name||''',cascade=>TRUE);
No. There is no need to gather index statistics immediately after index creation, since Oracle automatically gathers stats for indexes at creation time.
From documentation,
Oracle Database now automatically collects statistics during index
creation and rebuild.
I think it was way back in earlier releases, when you could use COMPUTE STATISTICS clause to start or stop the collection of statistics on an index. But, now this clause has been deprecated. Oracle Database now automatically collects statistics during index creation and rebuild. This clause is supported for backward compatibility and will not cause errors.

Locking table for more transactions

I am using Oracle 11g.
I am trying to realize scenario of concurrent loading into a table with index rebuild. I have few flows which are trying to realize this scenario:
1. load data from source,
2. transform the data,
3. turn off the index on DWH table,
4. load data into DWH,
5. rebuild index on DWH table.
I turn off and rebuild indexes for better performance, there are situations where one flow is rebuilding the index while the other tries to turn it off. What I need to do is to place some lock between points 2 and 3, which would be released after point 5.
Oracle built in LOCK TABLE mechanism is not sufficient, as the lock is released by the end of transaction, so any ALTER statement releases the lock.
The question is how to solve the problem?
Problem solved. What I wanted to do can be easily achieved using DBMS_LOCK package.
1. DBMS_LOCK.REQUEST(...)
2. ALTER INDEX ... UNUSABLE
3. Load data
4. ALTER INDEX ... REBUILD
5. DBMS_LOCK.RELEASE(...)
You can use DBMS_SCHEDULER:
run jobs that load and transform the data
turn off indexes
run jobs that load data into DWH
rebuild indexes
Using Chains:
http://docs.oracle.com/cd/B28359_01/server.111/b28310/scheduse009.htm#CHDCFBHG
You have to range partition your table on minutes/hours basis of insertion time and enable indexes only when time is up. Each partition should have all indexes disabled after creation. Only one process can enable indexes.

rebuilding sybase clustered indexes monthly occasionally fails

I am running into an issue dropping and recreating unique clustered indexes on some sybase databases. I have been unable to reproduce the issue in my test env.
The error that results when the concurrency issue arrises is as follows:
Cannot drop or modify partition descriptor database 'xxx' (43), object xx, index xx (0), partition 'xx' as it is in use. Please retry your command later. Total reference count '4'. Task reference count '2'.
I know an exclusive lock on a table or row from an open tran will not cause this, and I don't think anything the end-users could be doing would change the sort order of the data.
The data is a clustered round robin, and is a single partition table.
Please advise.
Could you use "reorg" instead - that'd have the same effect and should not be vulnerable to this? But I'm not sure because I like you don't see how this happens - building the new clustered index shouldn't start until Sybase gets a table lock (it has to for a clustered,) so why does it appear something else is accessing? (DBCCs, or something system level with locks on system catalogs maybe, so that although the index can build, something about updating the system catalogs fails?)
Before 15.0.3 esd 4 REORG causes other queries that try to access the table being reorged to fail, not to be blocked, which can be annoying.