Home » RDBMS Server » Performance Tuning » stale (local) index statistics on partitioned table (Oracle 12c)
|
|
Re: stale (local) index statistics on partitioned table [message #649780 is a reply to message #649779] |
Wed, 06 April 2016 04:34   |
 |
quirks
Messages: 85 Registered: October 2014
|
Member |
|
|
Good questions. I'll answer them as good as I can.
1st
I came up with this, because they are marked as stale.
2nd
I suspect, that they are not stale (besides the ones for the last partition, which was automatically created from oracle while inserting new data in a new time slice / partition). Is there a way to figure out if they are truly stale or only marked as stale?
3rd
The plans are changing, so I suspect the cause is the stale status. If I gather the stats again (which takes several hours) the plans become better again.
4th
There is an automatic (daily) gathering process setup by our DBA (I basically know nothing about this one).
Furthermore there is a gathering routine for the new daily partition (see below) which produces correct /valid stats.
Toggle Spoiler[code]CREATE OR REPLACE PROCEDURE PMDAT.ANALYZE_DWH_TABS(P_TABNAME VARCHAR2) IS
CURSOR C1 IS
SELECT
USER
FROM
DUAL
WHERE
ROWNUM = 1;
V_OWNER VARCHAR2(32) := NULL;
V_TABNAME VARCHAR2(32) := UPPER(P_TABNAME);
CURSOR C2 IS
SELECT
CASE
WHEN PARTITION_NAME IS NULL THEN
TABLE_NAME
ELSE
CASE
WHEN SUBPARTITION_NAME IS NULL THEN
PARTITION_NAME
ELSE
SUBPARTITION_NAME
END
END
ANALYZE_PARTITION
,CASE
WHEN PARTITION_NAME IS NULL THEN
'GLOBAL'
ELSE
CASE
WHEN SUBPARTITION_NAME IS NULL THEN
'PARTITION'
ELSE
'SUBPARTITION'
END
END
GRANULARITY
FROM
USER_TAB_STATISTICS
WHERE
COALESCE(STALE_STATS, 'YES') = 'YES'
AND TABLE_NAME = V_TABNAME
ORDER BY
2 DESC;
CURSOR C3 IS
SELECT
DISTINCT S.INDEX_NAME
,CASE
WHEN PARTITION_NAME IS NULL THEN
TABLE_NAME
ELSE
CASE
WHEN SUBPARTITION_NAME IS NULL THEN
PARTITION_NAME
ELSE
SUBPARTITION_NAME
END
END
ANALYZE_PARTITION
,CASE
WHEN PARTITION_NAME IS NULL THEN
'GLOBAL'
ELSE
CASE
WHEN SUBPARTITION_NAME IS NULL THEN
'PARTITION'
ELSE
'SUBPARTITION'
END
END
GRANULARITY
FROM
USER_IND_STATISTICS S
WHERE
S.STALE_STATS <> 'NO'
AND S.TABLE_NAME = V_TABNAME
order by 3 desc ;
BEGIN
FOR C1_REC IN C1 LOOP
V_OWNER := C1_REC.USER;
END LOOP;
FOR C2_REC IN C2 LOOP
IF C2_REC.GRANULARITY = 'GLOBAL' THEN
DBMS_STATS.GATHER_TABLE_STATS(
OWNNAME => V_OWNER
,TABNAME => V_TABNAME
,METHOD_OPT => 'FOR ALL INDEXED COLUMNS'
,GRANULARITY => C2_REC.GRANULARITY
,NO_INVALIDATE => FALSE
,DEGREE => 5
,CASCADE => TRUE
);
ELSE
DBMS_STATS.GATHER_TABLE_STATS(
OWNNAME => V_OWNER
,TABNAME => V_TABNAME
,PARTNAME => C2_REC.ANALYZE_PARTITION
,METHOD_OPT => 'FOR ALL INDEXED COLUMNS'
,GRANULARITY => C2_REC.GRANULARITY
,NO_INVALIDATE => FALSE
,DEGREE => 5
,CASCADE => TRUE
);
END IF;
END LOOP;
FOR C3_REC IN C3 LOOP
IF C3_REC.GRANULARITY = 'GLOBAL' THEN
DBMS_STATS.GATHER_INDEX_STATS(
OWNNAME => V_OWNER
,INDNAME => C3_REC.INDEX_NAME
,ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE
,DEGREE => 5
,GRANULARITY => C3_REC.GRANULARITY
,NO_INVALIDATE => FALSE
);
ELSE
DBMS_STATS.GATHER_INDEX_STATS(
OWNNAME => V_OWNER
,INDNAME => C3_REC.INDEX_NAME
,PARTNAME => C3_REC.ANALYZE_PARTITION
,ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE
,DEGREE => 5
,GRANULARITY => C3_REC.GRANULARITY
,NO_INVALIDATE => FALSE
);
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001, SQLCODE || SQLERRM);
END;
/
[/pre] [/align]
[Updated on: Wed, 06 April 2016 04:36] Report message to a moderator
|
|
|
|
Re: stale (local) index statistics on partitioned table [message #649797 is a reply to message #649788] |
Wed, 06 April 2016 07:26   |
 |
quirks
Messages: 85 Registered: October 2014
|
Member |
|
|
Well, I'm not a DBA. All I know is what I've read / heard. My understanding of how Oracle works is more guessing than knowing. But my guesswork matches very well to the info you just gave.
Toggle SpoilerAfaik (please correct me if I'm wrong), STALE means, that Oracle thinks that the statistic of how the values are spread out over the object in focus (table / partion / index / local index) has changed so much, that it is no longer a reliable source for the oracle optimizer to base its estimations on. 10% is the default value of changes in an object that can be varied before Oracle sets the Status to stale. This percentage can be set by the DBA.
"dba_tab_modifications" shows me exact the inserts in the new partition that I would expect.
When I look at "USER_IND_STATISTICS", I find partitions marked as "stale" that are not mentioned in "dba_tab_modifications" (but that probably might be the cause because I don't dare to "exec dbms_stats.flush_database_monitoring_info").
You said John Watson wrote on Wed, 06 April 2016 04:56If the stats have not changed, the plans will not change. Does that apply even if STALE_STATS = 'YES'?
I'm not sure if I can / should ALTER SYSTEM. But I obviously can recommend it to our DBA. Our current settings are :Toggle Spoiler SELECT NAME, VALUE
FROM V$PARAMETER
WHERE NAME IN ('optimizer_adaptive_features', 'optimizer_dynamic_sampling');
NAME VALUE
optimizer_dynamic_sampling 2
optimizer_adaptive_features TRUE
I've tried to set the options you've recommended as session parameters and indeed the plans became better. While playing around I figured that "optimizer_dynamic_sampling=0;" did the trick. "optimizer_adaptive_features=false;" seems to enable / disable the dynamic sampling as well.
Now I'm a little bit confused. Is it possible that "stale" index statistics do trigger oracle to do dynamic sampling? If so, that leads me back to my first question. Why do they get stale in the first place even if there is no change (in that specific partitions)?
|
|
|
|
Re: stale (local) index statistics on partitioned table [message #649799 is a reply to message #649798] |
Wed, 06 April 2016 08:12  |
 |
quirks
Messages: 85 Registered: October 2014
|
Member |
|
|
BlackSwan wrote on Wed, 06 April 2016 07:36you need to query different views for partitioned indexes as compared to "regular" indexes
For the usability of indices I've to look in the corresponding view. And I can see when it was analyzed.
For the index statistics I only know "USER_IND_STATISTICS". Can you probably give me a hint what to search for in google (I could not find any)?
[Updated on: Wed, 06 April 2016 08:19] Report message to a moderator
|
|
|
Goto Forum:
Current Time: Sat May 03 09:43:15 CDT 2025
|