Как сказать MySQL использовать больше индексов - PullRequest
0 голосов
/ 10 марта 2011

У меня проблема с запросом MySQL, который слишком медленный, потому что, по моему скромному мнению, индексация не работает должным образом.

У меня есть таблица, которая содержит 7 полей indexables и 3 BLOB-объекта данных.

CREATE TABLE IF NOT EXISTS `superstrat` (
  `idStrategy` int(11) NOT NULL AUTO_INCREMENT,
  `strategy_date` datetime NOT NULL,
  `strategy_type` int(11) NOT NULL,
  `strategy_supertype` int(11) NOT NULL,
  `strategy_codes` varchar(40) NOT NULL,
  `strategy_vols` blob NOT NULL,
  `strategy_prices` blob NOT NULL,
  `strategy_hedge` blob NOT NULL,
  `strategy_neutrality` int(11) NOT NULL,
  `strategy_valuation_model` int(11) NOT NULL,
  `strategy_source` int(11) NOT NULL,
  PRIMARY KEY (`idStrategy`),
  UNIQUE KEY `strategy_date` (`strategy_date`,`strategy_type`,`strategy_supertype`,`strategy_codes`,`strategy_neutrality`,`strategy_valuation_model`,`strategy_source`),
  KEY `strategy_date_2` (`strategy_date`),
  KEY `strategy_type` (`strategy_type`),
  KEY `strategy_supertype` (`strategy_supertype`),
  KEY `strategy_codes` (`strategy_codes`),
  KEY `strategy_neutrality` (`strategy_neutrality`),
  KEY `strategy_valuation_model` (`strategy_valuation_model`),
  KEY `strategy_source` (`strategy_source`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=888605 ;

Я делаю этот запрос, но он слишком медленный

SELECT * FROM test_ter.superstrat WHERE strategy_date >= '2004-01-01' AND strategy_type='0'
AND strategy_supertype = '0' AND strategy_valuation_model='6'
AND strategy_source ='0' AND strategy_codes='10;' AND strategy_neutrality='2' LIMIT 0,5000;

Причина в том, что он выполняет запрос index_merge только по двум индексам: стратегии_типа, стратегии_коды:

1   SIMPLE  superstrat  index_merge strategy_date,strategy_date_2,strategy_type,strategy_supertype,strategy_codes,strategy_neutrality,strategy_valuation_model,strategy_source  strategy_type,strategy_codes    4,42        6258    Using intersect(strategy_type,strategy_codes); Using where

Как я могу заставить index_merge на других полях, здесь он будет извлекать 6258 строк вместо 1,5 КБ, когда моя база данных заполнена, для извлечения 50000 строк потребуется 60 секунд, но я вполне уверен, что его можно уменьшить цель 1.5к, я просто не знаю как. ИНДЕКС ИСПОЛЬЗОВАНИЯ и ИНДЕКС СИЛЫ, похоже, не работают.

Ответы [ 2 ]

1 голос
/ 10 марта 2011

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

Когда часть данных вставляется в таблицу mysql, она записывается в файл на жестком диске.Как и во всем в жизни и на компьютерах, легче искать соответствующие данные в файле меньшего размера, чем в файле большего размера - следовательно, индексы.Индексы записываются в отдельный физический файл, и смысл файла индекса в том, что он меньше, чем файл данных, следовательно - поиск чего-либо в файле индекса происходит быстрее, и как только вы его там найдете, он сообщает вам, где в файле данных находится ваша запись.is.

Когда вы сейчас посмотрите на свою таблицу, вы заметите, как вы проиндексировали каждый возможный столбец, что, ну, в общем, плохо.Вам нужно четко подумать, КАК вы поможете компьютеру помочь.

Теперь индекс «лучший», если его селективность составляет 100%.Это означает, что если у вас есть 100 записей и вы проиндексировали столбец «idStrategy» - у вас будет 100 РАЗНЫХ значений индекса.Таким образом, число различных индексов VALUES, деленное на количество строк = селективность (прямо скажем).

Итак, вопрос здесь в том, какой столбец вы можете использовать для фильтрации наиболее эффективного набора данных?Первое, что приходит на ум - это столбец strategy_date.Он определен как уникальный ключ, его тип - datetime, поэтому он внутренне сохраняется как 4-байтовое целое число, что делает его идеальным кандидатом для поиска типа BETWEEN, и именно этот столбец будет иметь наибольшее значение при выборе чего-либо из вашего набора данных.

Другие столбцы, такие как strategy_neutrality и т. Д., Не могут иметь много разных значений, поэтому они плохо подходят для индекса, поэтому - их не нужно индексировать.

Немного добавить здесь, однако то, что я написал, должно дать вам хотя бы НЕКОТОРОЕ понимание того, как искать то, что неясно.Надеюсь, это поможет.

0 голосов
/ 10 марта 2011

Ну, я только что перешел с MyISAM на InnoDB на нем работает.

1   SIMPLE  superstrat  index_merge strategy_date,strategy_date_2,strategy_type,strategy_supertype,strategy_codes,strategy_neutrality,strategy_valuation_model,strategy_source  strategy_type,strategy_codes,strategy_source,strategy_supertype,strategy_neutrality,strategy_valuation_model    4,42,4,4,4,4        1248    Using intersect(strategy_type,strategy_codes,strategy_source,strategy_supertype,strategy_neutrality,strategy_valuation_model); Using where
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...