Мощность составного индекса Mysql не одинакова для всех полей

Я создал составной индекс в mysql, вот команда, которую я использую: создайте индекс Deliver_aid_sid_rcnt_idx на DELIVER_SM (AID, STATUSID, RETRY_CNT) USING BTREE; Странно то, что я получил разное значение кардинальности для каждого поля. это нормально? я также создал другой составной индекс, и значение мощности для каждого поля одинаково.

+--------------+-----------------+-------------+--------------------------+-------------+
| TABLE_SCHEMA | TABLE_NAME      | COLUMN_NAME | INDEX_NAME               | CARDINALITY |
+--------------+-----------------+-------------+--------------------------+-------------+
| prddb        | DELIVER_SM      | AID         | deliver_aid_sid_rcnt_idx |          28 |
| prddb        | DELIVER_SM      | STATUSID    | deliver_aid_sid_rcnt_idx |         286 |
| prddb        | DELIVER_SM      | RETRY_CNT   | deliver_aid_sid_rcnt_idx |         286 |
+--------------+-----------------+-------------+--------------------------+-------------+
 

person Antonios    schedule 24.09.2013    source источник


Ответы (1)


Мощность индекса – это не количество отдельных значений столбцов, а скорее количество узлов в индексе b-дерева.

Рассмотрим пример ниже:

CREATE TABLE abc(   a int, b int, c int );

set @x = 0;
INSERT INTO abc( a, b, c ) 
SELECT (@x:=@x+1),
       round( @x / 10 ),
       round( @x / 100 )
FROM information_schema.columns
LIMIT 421;

CREATE INDEX ix1 ON abc( a, b, c );
CREATE INDEX ix2 ON abc( c, b, a );

ANALYZE TABLE abc;

и запросы, которые показывают кардинальность индексов:

SELECT COUNT( distinct a) a,
       COUNT( distinct b) b,
       COUNT( distinct c) c,
       COUNT( * )
FROM abc;

SELECT table_name, index_name, column_name, cardinality
FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_name = 'abc' AND index_name = 'ix1';

SELECT table_name, index_name, column_name, cardinality
FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_name = 'abc' AND index_name = 'ix2';


Посмотрите на эту демонстрацию, чтобы увидеть результаты: http://www.sqlfiddle.com/#!2/b5987/1

В таблице 421 строка.
Столбец a содержит 421 уникальное значение.
Столбец b содержит 43 различных значения.
Столбец c содержит 5 различных значений.

Я плохо рисую, поэтому не прикрепляю сюда чертежи этих индексов b-дерева :)
Но я надеюсь, что вы можете представить изображение индекса b-дерева в своем head, как в этой ссылке: http://docs.oracle.com/cd/E11882_01/server.112/e25789/indexiot.htm
(Кстати, я рекомендую вам изучить этот материал, он связан с оракулом, а не MySql, но это отличное объяснение того, как работают индексы и как они организованы). введите здесь описание изображения

Для индекса ix1 ON abc( a, b, c ) MySql показывает следующие кардиналиты:
a -- > 407
b --> 407
c --> 407

Помните, что числа кардинальности не являются точными значениями, а являются приблизительными.

Здесь a является ведущим столбцом в индексе (это столбец с наибольшим количеством различных значений), и поэтому он создает большое количество узлов верхнего уровня в индексе. Остальные столбцы (их значения) также хранятся в этих узлах индекса верхнего уровня (или, возможно, «под ними»). b --> 101
a --> 407

В этом случае, когда c является ведущим столбцом индекса, MySql «думает» (оценивает), что индекс имеет 9 узлов «верхнего уровня». , значения b занимают 101 узел "ниже c", а a занимает 407 узлов в индексе.

person krokodilko    schedule 24.09.2013
comment
kordirko, ваш ответ имеет смысл, но не могли бы вы уточнить еще один момент: что если я всегда буду искать по всем 3 точным значениям: a, b и c, то какой индекс будет быстрее на огромных таблицах: [a, b, c] или [с, б, а]? - person Alex Kovshovik; 17.06.2014