Оптимизировать запрос с двумя предложениями "in" - PullRequest
2 голосов
/ 15 августа 2010

Я пытаюсь оптимизировать запрос на MySQL, выполнение которого занимает около 15-20 секунд.Моя таблица данных содержит около 10 миллионов строк, и запрос пытается вернуть 68 000 записей, которые соответствуют 144 полям «Выполнить» и 35 полям «Имя».Поскольку запрос использует два предложения in, мои индексы не кажутся очень полезными.

Вот запрос:

select * from data d where 
d.data_type='Result' and 
(d.run in ('8a7aee1f2a6232b1012a624da9201b92', '8a7aee1f2a6232b1012a625432a314ef' , 

... [144 runs]

)) and (d.name like 'itema[%]' or d.name like 'itemb[%]')

Вот определение таблицы

CREATE TABLE `data` (
  `data_type` varchar(31) NOT NULL,
  `id` char(32) NOT NULL,
  `entry_time` datetime default NULL,
  `name` varchar(255) NOT NULL,
  `step` int(11) default NULL,
  `value` double NOT NULL,
  `run` char(32) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `FK2EEFAA8ECCC6F3` (`run`),
  KEY `data2` (`run`,`step`),
  KEY `data3` (`data_type`,`name(10)`,`run`),
  CONSTRAINT `FK2EEFAA8ECCC6F3` FOREIGN KEY (`run`) REFERENCES `run_archive` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Объясните, что запрос использует ключевые данные 3.

id      select_type     table   type    possible_keys   key     key_len ref    rows    Extra
1       SIMPLE  d    range   FK2EEFAA8ECCC6F3,data2,data3    data3    223     NULL    113271  Using where

Я использовал для выполнения 144 запросов (по одному на каждый запуск).Похоже, что в два раза быстрее выполнить один запрос, но все еще слишком медленно.

Предложения по оптимизации?У меня есть следующие идеи:

  • Поиск магического индекса, который ускоряет
    до этого

  • Денормализация данных (было бы легко получитьизбавиться от пробежки, но
    сложнее для названия)

  • Разделение данных по разным таблицам (сложно сделать с моим подходом Java / Hibernate)

Или я просто спрашиваю здесь о невозможном?

Редактировать: оказалось, что самым большим исправлением было увеличение размера моего innodb_buffer_pool.После этого запрос сократился до полутора секунд.Я пометил как «ответ» исправление, которое немного улучшило его.

Ответы [ 2 ]

1 голос
/ 15 августа 2010

Рассмотрите возможность разделения result записей от таблицы data? Я не уловил, какой процент у вас result, но, возможно, стоит сравнить с Dev-копией вашей базы данных Prod.

Можете ли вы FK эти run значения? Если они могут быть использованы повторно (?), Возможно, создайте таблицу Run? Я предполагаю, что 144 совпадения строк, даже проиндексированные, медленнее, чем если бы они были int или smallint. Опять же, сравнительный анализ этого или любого другого предложения, очевидно, докажет теорию.

Как будет выглядеть разница в плане запроса, если вы не включите предложение like в атрибут * name?

0 голосов
/ 15 августа 2010

В зависимости от того, насколько избирательным является условие на run, может быть лучше предоставить индекс

data_type, run, name(10)

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

Кроме того, использование меньшего типа данных для идентификатора выполнения уменьшит размер индекса и ускорит сравнение.Это постоянное улучшение, но оно может стоить, независимо от того,

...