Тривиальный вопрос о максимальном количестве различных значений в индексе B-дерева - PullRequest
3 голосов
/ 13 июня 2019

Я пытаюсь узнать об индексации. Я посмотрел на фактические индексы, используемые в базе данных на работе.

Я посмотрел на два случайных индекса:

SELECT
INDEX_NAME, INDEX_TYPE, LEAF_BLOCKS, DISTINCT_KEYS 
FROM ALL_INDEXES
WHERE TABLE_NAME = 'TRANS'
AND INDEX_NAME IN ('TRANS_PK','TRANS_ORD_NO')

Это дает:

INDEX_NAME  | INDEX_TYPE | LEAF_BLOCKS | DISTINCT_KEYS |
TRANS_PK    | NORMAL     | 13981       |    3718619    | 
TRANS_ORD_NO| NORMAL     | 17052       |    43904      |

Это то, что не имеет смысла для меня; не должно отличаться (column_name) от фактической таблицы, чтобы получить то же число Это не так!

SELECT COUNT(DISTINCT ORD_NO) FROM trans

.. дает 20273

TRANS_PK - это индекс для столбца с именем NO.

SELECT COUNT(distinct NO) FROM trans

... дает 4 328 622

Что я не получаю здесь? Выделение отличного должно приводить к тому же номеру, что и в столбце «разные ключи» в таблице ALL_INDEXES?

Ответы [ 3 ]

3 голосов
/ 13 июня 2019

Представления словаря (включая ALL_INDEXES) не имеют данных в реальном времени, но новые статистические значения обновляются в течение времени анализа и становятся устаревшими с течением времени.

0 голосов
/ 14 июня 2019

Статистика индекса может быть собрана с помощью процедуры DBMS_STATS.GATHER_INDEX_STATS (). В приведенном ниже примере показано, как значение DISTINCT_KEYS обновляется после вставки строк и сбора статистики индекса. Обратите внимание, что Oracle по умолчанию выбирает процент данных в индексе, поэтому DISTINCT_KEYS может не отражать фактическое количество отдельных ключей в индексе. См. Параметр эстимейт_процента в ссылке ниже.

https://docs.oracle.com/database/121/ARPLS/d_stats.htm#ARPLS68575

SQL> CREATE TABLE foo AS SELECT LEVEL id FROM dual CONNECT BY LEVEL <= 5;

Table FOO created.

SQL> CREATE INDEX foo_idx ON foo(id);

Index FOO_IDX created.

SQL> SELECT * FROM foo;

        ID
----------
         1
         2
         3
         4
         5

SQL> SELECT distinct_keys FROM all_indexes WHERE table_name = 'FOO';

DISTINCT_KEYS
-------------
            5

SQL> INSERT INTO foo VALUES(6);

1 row inserted.

SQL> INSERT INTO foo VALUES(7);

1 row inserted.

SQL> COMMIT;

Commit complete.

SQL> 
SQL> SELECT distinct_keys FROM all_indexes WHERE table_name = 'FOO';

DISTINCT_KEYS
-------------
            5

-- Here's where we gather the statistics
SQL> EXECUTE DBMS_STATS.GATHER_INDEX_STATS('MYSCHEMA', 'FOO_IDX');

PL/SQL procedure successfully completed.

SQL> SELECT distinct_keys FROM all_indexes WHERE table_name = 'FOO';

DISTINCT_KEYS
-------------
            7
0 голосов
/ 13 июня 2019

Проверьте также здесь: https://docs.microsoft.com/en-us/sql/relational-databases/sql-server-index-design-guide?view=sql-server-2017 "Каждая строка индекса содержит значение ключа и указатель либо на страницу промежуточного уровня в B-дереве, либо на строку данных на уровне листа индекса."- так что помимо указателей данных у вас также есть много межуровневых листов.

...