关于 B 树索引中不同值的最大数量的简单问题
Trivial question about max number of distinct values in a B-tree index
我正在尝试了解索引。我查看了工作中数据库中使用的实际索引。
我查看了两个随机索引:
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 |
这对我来说毫无意义;与实际 table 不同的 (column_name) 不应该产生相同的数字吗?它没有!
SELECT COUNT(DISTINCT ORD_NO) FROM trans
..给出 20273
TRANS_PK 是名为 NO.
的列的索引
SELECT COUNT(distinct NO) FROM trans
... 给出 4 328 622
我没有得到什么? select distinct 的结果应与 "distinct keys" - ALL_INDEXES- table?
中的列相同
字典视图(包括 ALL_INDEXES
)没有 real-time 数据,但新的统计值会在分析期间刷新,并随着时间的推移变得陈旧。
也在这里检查:https://docs.microsoft.com/en-us/sql/relational-databases/sql-server-index-design-guide?view=sql-server-2017
"Each index row contains a key value and a pointer to either an intermediate level page in the B-tree, or a data row in the leaf level of the index." - 所以在数据指针之上你还有许多 cross-level 叶子。
可以使用 DBMS_STATS.GATHER_INDEX_STATS() 过程收集索引统计信息。下面的示例显示了如何在插入行和收集索引统计信息后更新 DISTINCT_KEYS 值。请注意,默认情况下,Oracle 会从索引中抽取一定百分比的数据,因此 DISTINCT_KEYS 可能无法反映索引中不同键的实际数量。请参阅下面 link 中的 estimate_percent 参数。
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
我正在尝试了解索引。我查看了工作中数据库中使用的实际索引。
我查看了两个随机索引:
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 |
这对我来说毫无意义;与实际 table 不同的 (column_name) 不应该产生相同的数字吗?它没有!
SELECT COUNT(DISTINCT ORD_NO) FROM trans
..给出 20273
TRANS_PK 是名为 NO.
的列的索引SELECT COUNT(distinct NO) FROM trans
... 给出 4 328 622
我没有得到什么? select distinct 的结果应与 "distinct keys" - ALL_INDEXES- table?
中的列相同字典视图(包括 ALL_INDEXES
)没有 real-time 数据,但新的统计值会在分析期间刷新,并随着时间的推移变得陈旧。
也在这里检查:https://docs.microsoft.com/en-us/sql/relational-databases/sql-server-index-design-guide?view=sql-server-2017 "Each index row contains a key value and a pointer to either an intermediate level page in the B-tree, or a data row in the leaf level of the index." - 所以在数据指针之上你还有许多 cross-level 叶子。
可以使用 DBMS_STATS.GATHER_INDEX_STATS() 过程收集索引统计信息。下面的示例显示了如何在插入行和收集索引统计信息后更新 DISTINCT_KEYS 值。请注意,默认情况下,Oracle 会从索引中抽取一定百分比的数据,因此 DISTINCT_KEYS 可能无法反映索引中不同键的实际数量。请参阅下面 link 中的 estimate_percent 参数。
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