Alors pour ceux qui ont des doutes sur les performances de SQL sur des grosses tables, un exemple sur une base où je passais par hasard ce matin. Je n'ai changé que les noms de table/schema
La table fait 3.5 Tera, contient 400 millions de lignes:
Un requête courante fait un accès par index comme celui-ci:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 SQL> select num_rows,blocks from dba_tables where owner='XXX' and table_name='OP'; NUM_ROWS BLOCKS ---------- ---------- 398327400 236418039 Elapsed: 00:00:00.01 SQL> select blocks,bytes/1024/1024/1024/1024 TB from dba_segments where owner='XXX' and segment_name='OP'; BLOCKS TB ---------- ---------- 238309992 3.5510956
Donc 4 secondes. Et voici le plan d'exécution avec les statistiques d'exécution:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 SQL> select sum(length(data_segment)) from "XXX"."OP" where DECODE("REFERENCE",'0',"ENTITY","REFERENCE") between '000931151470664' and '000931181978026'; SUM(LENGTH(DATA_SEGMENT)) ------------------------- 8854698 Elapsed: 00:00:04.03
C'est bien un accès à la table, par index. Seulement quelques pages lues (quelques pages d'index puis une page par ligne). Toutes lues sur disque ici. L'index B-Tree a une hauteur de 3 branches ici. Avec 300 milliard de lignes, il aurait peut-être une hauteur de 4 ou 5 -> juste une ou de page de plus à lire -> impact négligeable sur le temps d'exécution.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 SQL> select * from table(dbms_xplan.display_cursor(format=>'allstats last')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------------------------------------ SQL_ID cg9fkkb28t3xs, child number 0 ------------------------------------- select sum(length(data_segment)) from "XXX"."OP" where DECODE("REFERENCE",'0',"ENTITY","REFERENCE") between '000931151470664' and '000931181978026' Plan hash value: 2490914298 ------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | ------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:04.02 | 610 | 608 | | 1 | RESULT CACHE | 4zy76myzu25zg9f8v75dy3awb0 | 1 | | 1 |00:00:04.02 | 610 | 608 | | 2 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:04.01 | 610 | 608 | | 3 | TABLE ACCESS BY INDEX ROWID| OP | 1 | 6 | 604 |00:00:04.01 | 610 | 608 | |* 4 | INDEX RANGE SCAN | AK1_OP | 1 | 6 | 604 |00:00:00.01 | 6 | 4 | -------------------------------------------------------------------------------------------------------------------------------
Et encore, on n'est pas en parallel query ici, il n'y a aucun partitionnement, aucune compression. On pourrait aller beaucoup plus loin. Et on est dans le cas le pire: rien encache (autant de 'Reads' que de Buffers') et lignes dispersées dans des blocs différents (Buffers=A-rows). C'est une appli qui a plus de 15 ans, utilisée tous les jours et qui tourne sans aucune administration à part rajouter des datafiles, sur un vieux serveur!
Cordialement,
Franck.
Partager