SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 01.02.2012 12:57:19

AlexandrD
Участник
Зарегистрирован: 01.02.2012
Сообщений: 2

Не используются все колонки в индексе

Здравствуйте!

MySQL 5.5.19.Помогите разобраться с индексами.

Есть две маленькие таблицы-"справочники". примерно по 50 записей в каждой.

CREATE TABLE `a` (
  `ida` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(45) COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`ida`)
) ENGINE=InnoDB

CREATE TABLE `b` (
  `idb` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(45) COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`idb`)
) ENGINE=InnoDB

И одна большая, которая их использует.Примерно 7 000 000 записей.
CREATE TABLE `state` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `ida` int(10) unsigned NOT NULL,
  `idb` int(10) unsigned NOT NULL,
  `dt` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_a_ida` (`ida`),
  KEY `fk_b_idb` (`idb`),
  KEY `index_1` (`ida`,`idb`,`dt`),
  CONSTRAINT `fk_a_ida` FOREIGN KEY (`ida`) REFERENCES `a` (`ida`) ,
  CONSTRAINT `fk_b_idb` FOREIGN KEY (`idb`) REFERENCES `b` (`idb`) ,
) ENGINE=InnoDB

Table    Non_unique    Key_name    Seq_in_index    Column_name    Collation    Cardinality    Sub_part    Packed    Null    Index_type
state    0    PRIMARY        1    id    A    7238053    NULL    NULL        BTREE       
state    1    fk_a_ida    1    ida    A    18    NULL    NULL        BTREE       
state    1    fk_b_idb    1    idb    A    18    NULL    NULL        BTREE       
state    1    index_1        1    ida    A    18    NULL    NULL        BTREE       
state    1    index_1        2    idb    A    6598    NULL    NULL        BTREE       
state    1    index_1        3    dt    A    6598    NULL    NULL        BTREE       
-----------------------------------------------------------
Делаем выборку(STRAIGHT_JOIN стоит намеренно ради эксперимента):
explain select STRAIGHT_JOIN state.id,a.name,b.name,state.dt
  from ((a join b) join state)
  where state.ida = a.ida and state.idb = b.idb
  and state.dt BETWEEN '2011-06-22 23:00:00' AND '2011-06-23 00:00:00'  ;

Получаем:
id    select_type    table    type    possible_keys            key    key_len    ref                rows    Extra
1    SIMPLE        a    ALL    PRIMARY                NULL    NULL    NULL                31   
1    SIMPLE        b    ALL    PRIMARY                NULL    NULL    NULL                57    "Using join buffer"
1    SIMPLE        state    ref    fk_a_ida,fk_b_idb,index_1    index_1    8    a.ida,b.idb    1097    "Using where; Using index"

ПОЧЕМУ mySQL не использовал третью колонку `dt` индекса  для выборки диапазона?

Неактивен

 

#2 01.02.2012 14:55:24

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Не используются все колонки в индексе

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

Чтобы убедиться — уберите условие с датой и посмотрите на оценку количества
строк.

Неактивен

 

#3 01.02.2012 15:39:13

AlexandrD
Участник
Зарегистрирован: 01.02.2012
Сообщений: 2

Re: Не используются все колонки в индексе

paulus написал:

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

Чтобы убедиться — уберите условие с датой и посмотрите на оценку количества
строк.

select STRAIGHT_JOIN state.id,a.name,b.name,state.dt
  from ((a join b) join state)
  where state.ida = a.ida and state.idb = b.idb
  ;
id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    a    ALL    PRIMARY    NULL    NULL    NULL    31   
1    SIMPLE    b    ALL    PRIMARY    NULL    NULL    NULL    57    "Using join buffer"
1    SIMPLE    state    ref    fk_a_ida,fk_b_idb,index_1    index_1    8    a.ida,.b.idb    1824    "Using index"
-----------------------------------------------------------------

Я привел не совсем показательный select.Все выдаваемые поля присутствуют в индексе и похоже не сканируется сама таблица.

Добавим колонку в таблицу state и попробуем сделать select с этим полем:
ALTER TABLE `gorsvet`.`state` ADD COLUMN `test` VARCHAR(45) NULL ;

explain select STRAIGHT_JOIN state.id,a.name,b.name,state.dt,state.test
  from ((a join b) join state)
  where state.ida = a.ida and state.idb = b.idb
   and state.dt BETWEEN '2011-06-22 23:00:00' AND '2011-06-23 00:00:00'
  ;
id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    a    ALL    PRIMARY    NULL    NULL    NULL    31   
1    SIMPLE    b    ALL    PRIMARY    NULL    NULL    NULL    57    "Using join buffer"
1    SIMPLE    state    ref    fk_a_ida,fk_b_idb,index_1    index_1    8    a.ida,b.idb    1824    "Using where"

Вот тут то уж точно третья колонка 'dt' индекса  не используется. type=ref, key_len=8(ida+idb).
Да и время выполнения запроса - 12288 rows in set (8 min 51.85 sec).

Неактивен

 

#4 02.02.2012 01:22:17

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Не используются все колонки в индексе

Угу, в данном случае не понятно. Ну то есть логика рассуждений такая — Вы выбираете
почти все данные без условия, поэтому полный скан должен работать быстрее выборки
по индексу. Проблема в том, что seekи всё равно уже будут, и в этом месте, кажется,
таки бага. sad

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson