Оптимизация медленного запроса в базе данных MySql InnoDB - PullRequest
2 голосов
/ 10 февраля 2011

У меня есть база данных MySql с очень медленным запросом. Я стараюсь изо всех сил, чтобы заставить это работать лучше, но не вижу, что я делаю здесь неправильно. Может быть, вы можете?

CREATE TABLE `tablea` (
    `a` int(11) NOT NULL auto_increment,
    `d` mediumint(9) default NULL,
    `c` int(11) default NULL,
    PRIMARY KEY  (`a`),
    KEY `d` USING BTREE (`d`)
) ENGINE=InnoDB AUTO_INCREMENT=1867710 DEFAULT CHARSET=utf8;

CREATE TABLE `tableb` (
    `b` int(11) NOT NULL auto_increment,
    `d` mediumint(9) default '1',
    `c` int(10) NOT NULL,
    `e` mediumint(9) default NULL,
    PRIMARY KEY  (`b`),
    KEY `c` (`c`),
    KEY `d` (`d`),
) ENGINE=InnoDB AUTO_INCREMENT=848150 DEFAULT CHARSET=utf8;

Запрос:

SELECT tablea.a, tableb.e
FROM tablea
INNER JOIN tableb ON (tablea.c=tableb.c) AND (tablea.d=tableb.d OR tableb.d=1)
WHERE tablea.d=100

Этот запрос выполняется за 10 секунд, если tablea.d = 100 дает 1500 строк и (tablea.d = tableb.d ИЛИ tableb.d = 1) дает 1600 строк. Это кажется очень медленным. Мне нужно сделать это намного быстрее, но я не вижу, что я делаю неправильно.

MySql EXPLAIN выводит:

id   select_type table   type   possible_keys key key_len ref       rows  Extra
1    SIMPLE      tablea  ref    d             d   4       const     1092  Using where
1    SIMPLE      tableb  ref    c,d           c   4       tablea.c  1     Using where

1 Ответ

0 голосов
/ 22 августа 2011

Если меня не смущает OR, запрос эквивалентен:

SELECT tablea.a, tableb.e
FROM tablea
  INNER JOIN tableb
    ON  tablea.c = tableb.c 
WHERE tablea.d = 100
  AND tableb.d IN (1,100) 

Попробуйте его (используя EXPLAIN) с различными индексами.Индекс в поле d (в обеих таблицах) поможет.Возможно больше, индекс на (d,c).

...