Низкая производительность MySQL Join - PullRequest
3 голосов
/ 18 сентября 2010

Я пытался выполнить объединение двух таблиц в MySQL, и запрос будет выполняться в течение минуты или двух, прежде чем у меня закончится память без получения результатов. Я далеко не эксперт по базам данных, поэтому я не уверен, плохо ли я пишу свои запросы, плохо ли настроены некоторые параметры MySQL или мне действительно нужно что-то делать полностью с моим запросом. К вашему сведению, база данных находится локально на моей машине.

У меня есть большая таблица (~ 2 миллиона записей), где один из столбцов является идентификатором в маленькой таблице (~ 3000 записей). В случае, если это имеет значение, идентификатор не уникален в большой таблице, но уникален в маленькой таблице. Я пробовал различные варианты следующего запроса, но, похоже, ничего не работает:

SELECT big_table.*, 
       small_table.col 
  FROM big_table 
left outer join small_table on (big_table.small_id = small_table.id)

Я много анализирую данные, для которых требуются все 2 миллиона строк, хотя не обязательно в одном запросе. Вот результаты моего "show create table":

'big_table', 'CREATE TABLE 'big_table' (
  'BIG_ID_1', varchar(12) NOT NULL,
  'BIG_ID_2', int(100) NOT NULL,
  'SMALL_ID' varchar(8) DEFAULT NULL,
  'TYPICAL_OTHER_COLUMN' varchar(3) DEFAULT NULL,
  ...
  PRIMARY KEY ('BIG_ID_1', 'BIG_ID_2')
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1'

'small_table', 'CREATE TABLE `small_table` (
  `id`, varchar(8) NOT NULL DEFAULT '''',
  `col`, varchar(1) DEFAULT NULL,
  ...
  PRIMARY KEY (`id`),
  KEY `inx_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1'

Вот результат "объяснения" для одного из моих запросов кандидатов:

id  select_type  table        type    possible_keys   key      key_len  ref                         rows     extra
1   SIMPLE       big_table    ALL     NULL            NULL     NULL     NULL                        1962193       
1   SIMPLE       small_table  eq_ref  PRIMARY,inx_id  PRIMARY  10       db_name.big_table.SMALL_ID  1             

1 Ответ

3 голосов
/ 18 сентября 2010

Вы выбираете около 2 миллионов записей в одном запросе.В зависимости от объема данных в каждой строке это могут быть сотни мегабайт данных, которые вы запрашиваете.

То, что вы можете попробовать:

  • Если вам не нужноЗатем все столбцы запрашивают столбцы, которые вам нужны, вместо использования SELECT table.*.
  • Посмотрите, можете ли вы перенести часть (или все) обработки в базу данных вместо того, чтобы извлекать данные и обрабатывать их в клиенте.
  • Избегайте чтения всего набора результатов в память за один раз.
  • Обрабатывайте строки по несколько тысяч раз за раз, а не извлекайте их все сразу.
...