Запрос на поиск несуществующих строк (LEFT JOIN) ведет себя по-разному...

vvs_rostov

Новичок
Запрос на поиск несуществующих строк (LEFT JOIN) ведет себя по-разному...

Здравствуйте.
Просмотрел рекомендации из мануала по оптимизации LEFT JOIN и, насколько подсказывает уровень моих знаний , ошибки в конфигурации индексов и таблиц нет. Кроме того на разрабатываемой платформе (ver. MySQL 5.0.45) запрос выполняется очень быстро (0.06 сек). При переносе на платформу хостинга (ver. MySQL 5.0.54) возникла проблема - запрос выполняется очень долго - несколько минут.

Имеем две таблицы.
1. Рабочая таблица.

CREATE TABLE `temp_price` (
`pr_name` char(30) NOT NULL default '',
`ch_num` char(30) NOT NULL default '',
`ch_name` char(255) NOT NULL default '',
`price` char(10) NOT NULL default '',
`cur_id` tinyint(3) unsigned NOT NULL default '0',
`id_post` tinyint(4) NOT NULL default '0',
`id_pr` int(5) unsigned NOT NULL default '0',
`id_ch` int(12) unsigned NOT NULL default '0',
`srok` tinyint(4) NOT NULL default '0',
KEY `NewIndex` (`ch_num`),
KEY `NewIndex2` (`id_pr`),
KEY `NewIndex3` (`id_ch`),
KEY `pr_name` (`pr_name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

2.Таблица.

CREATE TABLE `pr_old` (
`id_pr` int(4) unsigned NOT NULL auto_increment,
`pr_name` char(30) NOT NULL,
UNIQUE KEY `NewIndex` (`pr_name`),
KEY `id_pr` (`id_pr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Нужно выбрать такие различные pr_name из первой таблицы temp_price, которых нет в таблице pr_old.
Использую запрос:
SELECT DISTINCT temp_price.pr_name FROM temp_price LEFT JOIN pr_old ON temp_price.pr_name = pr_old.pr_name WHERE pr_old.id_pr IS NULL

На разрабатываемой машине Explain:
id, select_type, table,type, possible_keys,key,key_len,ref,rows,Extra
1, SIMPLE, temp_price, index,, pr_name,30,,7228,Using index; Using temporary
1, SIMPLE, pr_old, eq_ref, NewIndex, NewIndex,30,avtospros.temp_price.pr_name,1,Using where; Not exists; Distinct


На хостинге:
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,temp_price,index,NULL,pr_name,90,NULL,12050,Using index; Using temporary
1,SIMPLE,pr_old,ALL,NULL,NULL,NULL,NULL,1925,Using where; Not exists; Distinct

P.S. Очень плохо выглядят здесь эти Explain, в первой Rows 7228; 1 во второй 12050; 1925
Данные в temp_price отличаются , в pr_old одинаковые.


Пробовал использовать USE INDEX во втором запросе - указывал те которые индексы выбирались в первом - не привело к результату. Что подскажете?
Спасибо.
 

Gas

может по одной?
может на продакшене у таблицы temp_price стал charset utf8 (или конкретно у этого поля), key_len=90 при поле char(30) и из-за этого не работает связь по индексу с таблицей pr_old где остался latin1.
USE INDEX только предлагает использовать индекс, force index - обязывает.
 

vvs_rostov

Новичок
Спасибо за совет.
Сейчас по пробую в этом направлении попробовать решить вопрос...

-~{}~ 21.03.08 17:24:

Теперь думаю что проблема в этом, но затрудняюсь с решением.
Данные pr_old, перезанес с помощью mysqldump. Указав кодировку latin1.
Но опять указано key_len = 90.
В настройках my.conf - все кодировки latin1;

Данные в temp_price заносятся php-скриптом, при соединении с БД вызывается команда SET NAMES 'latin1'.
 

Gas

может по одной?
vvs_rostov
для начала нужно просто сравнить вывод show create table `temp_price`; на обоих серверах. Данные, set names и т.д. пока не важны.
 

vvs_rostov

Новичок
Спасибо большое. Разобрался. Оказывается на сервера по умолчанию кодировка у temp_price устанавливалась utf.

-~{}~ 24.03.08 16:34:

Хочу поделиться курьёзной проблемой которая, отвлекала с утра.
Запрос SELECT по индексированному полю очень долго выполнялся (таблица 3 млн записей, время около 1000 сек), все это проделывал на клиенте MySQL.
Измененял параметры тонкой запросов, менял поля запроса и т.д. - ничего не помогало. Оказывается результат выборки просто долго шел по нескокрстному каналу 128 кбит.
 
Сверху