web-dev-qa-db-fra.com

Qu'est-ce que cela signifie lorsque last_analyzed et stale_stats est null

Nous exécutons actuellement Oracle 11g et je cherche à savoir si nous devons exécuter des statistiques après une importation importante. Le niveau de statistiques est défini sur "TYPIQUE". Sur cette base, je pense que nous n'avons PAS besoin de mettre à jour les statistiques:

Depuis Oracle Database 11g, les mots clés MONITORING et NOMONITORING sont obsolètes et les statistiques sont collectées automatiquement.

https://docs.Oracle.com/cd/B28359_01/server.111/b28310/tables005.htm

Cependant, après avoir créé ma base de données et exécuté mon importation modeste (des centaines de milliers à des millions d'enregistrements dans une poignée de tables et la création d'un certain nombre d'index), toutes les tables affectées par l'importation affichent null pour last_analyzed et stale_stats à l'aide de la requête au dessous de.

select 
    table_name, 
    stale_stats, 
    last_analyzed
from 
    dba_tab_statistics
 where 
    owner = 'MY_SCHEMA'
order by 
    last_analyzed desc, table_name asc
;

Dois-je m'attendre à ce que certaines requêtes aient de mauvaises performances dans cet état?

Dois-je m'attendre à ce que les statistiques finissent par s'exécuter et que last_analyzed et stale_stats soient éventuellement renseignés (la documentation suggère que ces valeurs sont mises à jour toutes les trois heures par défaut)?

D'après mon expérience, pour les bases de données de taille moyenne (tables avec des millions d'enregistrements et moins de 10 millions d'enregistrements), le nettoyage avec des statistiques n'est pas nécessaire et provoque généralement plus de problèmes qu'il n'en résout. Est-ce généralement le cas?

* * * NOTES SUR NOTRE RÉSOLUTION * * *

Nous utilisions ceci:

analyze table my_table compute statistics

Nous sommes passés à ceci:

dbms_stats.gather_table_stats('MY_SCHEMA', 'MY_TABLE');

La déclaration de la table d'analyse a pris environ 1h30 minutes dans un environnement et environ 15h00 - 20h00 minutes dans le deuxième environnement.

L'instruction recueillir_table_stats a pris environ 0:30 à 1:00 minutes dans les deux cas que nous avons pu examiner.

Notre plan pour l'avenir est de basculer nos instructions de table d'analyse vers les appels de collecte_table_stats.

4
John

STATISTICS_LEVEL et la collecte de statistiques de table/index sont des choses entièrement différentes. STATISTICS_LEVEL affecte si les statistiques de source de ligne sont collectées pendant l'exécution de la commande. Ainsi, vous pouvez comparer les estimations de l'optimiseur et les valeurs réelles pour chaque étape du curseur d'affichage.

Les statistiques de table/d'index sont donc utilisées pour l'optimisation du plan d'exécution et STATISTICS_LEVEL pour collecter les statistiques d'exécution lorsque le plan d'exécution est en cours d'exécution et principalement à des fins de diagnostic.

Quand last_analyzed est nul, cela signifie que les statistiques de table n'ont pas encore été collectées.

stale_stats indique si les statistiques sont considérées comme fraîches ou périmées, ou si les statistiques seront collectées automatiquement la prochaine fois ou non. Les paramètres par défaut sont de 10%. Si vous collectez des statistiques de table, puis insérez/mettez à jour/supprimez moins de 10% des lignes, les statistiques sont considérées comme récentes. Lorsque vous atteignez 10% des lignes modifiées, elles deviennent périmées.

Oracle par défaut recueille automatiquement les statistiques de table/index pendant la fenêtre de maintenance qui est automatiquement configurée lors de la création d'une base de données. Il est généralement reconfiguré par les administrateurs de base de données s'il existe des exigences spécifiques.

En ce qui concerne la STATISTICS_LEVEL, avec la valeur par défaut TYPICAL cela ressemble à ceci:

HUSQVIK@hq_pdb_tcp> select * from dual;

D
-
X
HUSQVIK@hq_pdb_tcp> SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------
SQL_ID  a5ks9fhw2v9s1, child number 0
-------------------------------------
select * from dual

Plan hash value: 272002086

-------------------------------------------
| Id  | Operation         | Name | E-Rows |
-------------------------------------------
|   0 | SELECT STATEMENT  |      |        |
|   1 |  TABLE ACCESS FULL| DUAL |      1 |
-------------------------------------------

Note
-----
   - Warning: basic plan statistics not available. These are only collected when:
       * hint 'gather_plan_statistics' is used for the statement or
       * parameter 'statistics_level' is set to 'ALL', at session or system level

Nous ne voyons rien de plus que le nombre estimé de lignes. Si vous définissez ALTER SESSION SET statistics_level = ALL puis

HUSQVIK@hq_pdb_tcp> ALTER SESSION SET statistics_level = ALL;
HUSQVIK@hq_pdb_tcp> select * from dual;

D
-
X
HUSQVIK@hq_pdb_tcp> SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------
SQL_ID  a5ks9fhw2v9s1, child number 1
-------------------------------------
select * from dual

Plan hash value: 272002086

------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |      1 |00:00:00.01 |       3 |
|   1 |  TABLE ACCESS FULL| DUAL |      1 |      1 |      1 |00:00:00.01 |       3 |
------------------------------------------------------------------------------------

Maintenant, nous voyons également le nombre réel de lignes et le temps nécessaire pour exécuter chaque étape ainsi que le nombre de lectures cohérentes (colonne tampons).

Avec des requêtes plus complexes, vous obtiendrez beaucoup plus d'informations que cela. Vous devriez vérifier la documentation à https://docs.Oracle.com/database/121/ARPLS/d_xplan.htm

Sachez également que l'échantillonnage des statistiques n'est pas effectué avec chaque ligne mais par défaut toutes les 128 lignes (peut être modifié à l'aide de _rowsource_statistics_sampfreq paramètre)

4
Husqvik

(Husqvik a expliqué en détail la signification des colonnes et des paramètres, cette réponse ne traite que de la façon de recueillir des statistiques.)

Les statistiques doivent être collectées manuellement après toute* passer à une table. Oracle dispose d'un excellent processus de collecte de statistiques automatique par défaut depuis 11g. Mais même avec ce nouveau système, il y a encore au moins deux bonnes raisons de collecter manuellement des statistiques. La tâche automatique de collecte de statistiques par défaut est normalement destinée aux tables OLTP à évolution lente, et non aux tables d'entrepôt de données à évolution rapide).

  1. Des modifications importantes des données peuvent facilement entraîner des problèmes de performances importants. Si les tables doivent être utilisées juste après leur chargement, elles ont immédiatement besoin de bonnes statistiques.

    Un problème courant dans les processus ETL est lorsque les tables passent d'une ligne à un million de lignes. L'optimiseur pense qu'il n'y a toujours qu'une seule ligne dans les grands tableaux et utilise de nombreuses jointures de boucles imbriquées au lieu de jointures de hachage. Ces algorithmes fonctionnent bien dans différents contextes; sans bonnes statistiques, Oracle ne connaît pas le bon contexte.

    Il est important de noter qu'un NULL LAST_ANALYZED n'est pas le pire des cas. Lorsqu'il n'y a aucune statistique, Oracle utilise l'échantillonnage dynamique pour générer des estimations statistiques rapides. Le pire des cas est lorsque le travail de statistiques s'est exécuté la nuit dernière lorsque la table est vide; Oracle pense qu'il a de bonnes statistiques quand ce n'est vraiment pas le cas.

  2. La tâche automatique de statistiques peut ne pas être en mesure de suivre les modifications importantes. La tâche automatique de statistiques est un processus monothread à faible priorité. S'il reste trop de grandes tables au processus automatique, il peut ne pas être en mesure de les traiter pendant la fenêtre de maintenance.


La mauvaise nouvelle est que les développeurs ne peuvent pas ignorer les statistiques de l'optimiseur. Les administrateurs de base de données ne peuvent pas simplement gérer cela plus tard. Il peut être utile de lire certains des chapitres des manuels, tels que Gestion des statistiques de l’optimiseur .

La bonne nouvelle, c'est qu'Oracle 11g a enfin les paramètres par défaut de Nice. Vous n'avez généralement pas besoin de fouiner avec les paramètres. Dans la plupart des cas, il existe une règle simple à suivre: si la table a changé de manière significative, exécutez ceci:

dbms_stats.gather_table_stats('SCHEMA_NAME', 'TABLE_NAME');

*: "Significatif" est un mot subjectif. Un changement est normalement significatif en termes de taille relative, et non absolu. L'ajout d'un million de lignes à une table est significatif si la table a actuellement une ligne, mais pas si la table a un milliard de lignes.

1
Jon Heller