Почему мое простое внешнее соединение mysql занимает так много времени?

Я знаю, что это обычная проблема, но я не могу найти проблему, почему внешнее соединение с этими двумя простыми таблицами занимает так много времени.

Я убедился, что они оба - myisam, одна и та же кодировка.

CREATE TABLE `pinventory` (
  `article` char(10) CHARACTER SET latin1 NOT NULL,
  `inventory` int(11) DEFAULT NULL,
  `store_id` char(10) CHARACTER SET latin1 DEFAULT NULL,
  `status` char(1) CHARACTER SET latin1 DEFAULT NULL,
  `what` int(11) DEFAULT NULL,
  PRIMARY KEY (`article`),
  KEY `article` (`article`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

-- pinventory has 59310 rows

CREATE TABLE `products` (
  `productid` int(11) NOT NULL DEFAULT '0',
  `prodcode` varchar(250) NOT NULL DEFAULT '',
  `prodname` varchar(250) NOT NULL DEFAULT '',
  `prodtype` smallint(6) NOT NULL DEFAULT '0',
 ...
  PRIMARY KEY (`productid`),
  KEY `prodcode` (`prodcode`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

-- products has 7978 rows

SELECT prodcode, prodname, "not in inventory"
FROM products
LEFT OUTER JOIN pinventory ON article = prodcode
WHERE article IS NULL
;  

-- takes 2 minutes and 33 seconds and returns the correct 476 rows

-- explain

    id select_type     table      type  possible_keys  key     key_len    ref      rows   Extra
    1 SIMPLE       products        ALL   (NULL)       (NULL)   ( NULL)   (NULL)     7978
    1 SIMPLE       pinventory      index (NULL)        PRIMARY  10        (NULL)    59310  Using where; Using index; Not exists

inner join takes .22 seconds
SELECT prodcode, prodname, "in inventory"
FROM products
JOIN pinventory ON article = prodcode
;  

Я попытался заменить «article» на varchar (250), чтобы оба поля в соединении были одинаковыми, но это не помогло.

Благодарность


person sdfor    schedule 14.06.2013    source источник


Ответы (1)


В ваших ключах article и prodcode используются разные наборы символов.

pinventory.article: char(10) CHARACTER SET latin1
products.prodcode: varchar(250) CHARACTER SET utf8

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

Попробуйте использовать один и тот же набор символов в обоих полях, вы почувствуете разницу.

person Bjoern    schedule 14.06.2013
comment
Хорошо поймал! Я не знаю, почему я позволил той же кодировке в описании ввести меня в заблуждение. - person ; 15.06.2013
comment
Отлично, я не знал, что для столбцов есть отдельные наборы символов. Я никогда не устанавливал их, и sqlyog по умолчанию не показывает этого - нужно убрать галочку с опций скрытия языка. Спустился до 0,4 секунды. Как сказал ебыроб Хороший улов! - person sdfor; 15.06.2013