MySQL: какие индексы использовать для простого выбора диапазона? - PullRequest
2 голосов
/ 14 сентября 2010

У меня есть таблица с ~ 30 миллионами строк (и растет!), И в настоящее время у меня есть некоторые проблемы с простым выбором диапазона.

Запрос выглядит следующим образом:

<code>SELECT SUM( CEIL( dlvSize / 100 ) ) as numItems
FROM log
WHERE timeLogged BETWEEN 1000000 AND 2000000
AND user = 'example'

Требуются минуты, чтобы закончить, и я думаю, что решение будет по индексам, которые я использую. Вот результат объяснения:

+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+
| id | select_type | table | type  | possible_keys                   | key     | key_len | ref  | rows     | Extra       |
+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+
|  1 | SIMPLE      | log   | range | PRIMARY,timeLogged              | PRIMARY | 4       | NULL | 11839754 | Using where | 
+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+

Моя структура таблицы такая (уменьшена, чтобы она лучше подходила к проблеме):

CREATE TABLE IF NOT EXISTS `log` (
  `origDomain` varchar(64) NOT NULL default '0',
  `timeLogged` int(11) NOT NULL default '0',
  `orig` varchar(128) NOT NULL default '',
  `rcpt` varchar(128) NOT NULL default '',
  `dlvSize` varchar(255) default NULL,
  `user` varchar(255) default NULL,
  PRIMARY KEY  (`timeLogged`,`orig`,`rcpt`),
  KEY `timeLogged` (`timeLogged`),
  KEY `orig` (`orig`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Есть идеи, что можно сделать, чтобы оптимизировать этот запрос или индексы в моей таблице?

Ответы [ 3 ]

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

Вы можете попробовать добавить составной индекс в (user, timeLogged):

CREATE TABLE IF NOT EXISTS `log` (
  ...
  KEY `user_timeLogged` (user, timeLogged),
  ...
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Связанный пост переполнения стека:

1 голос
/ 14 сентября 2010

В дополнение к предложениям других ответов отмечу, что в таблице есть столбец user, который является varchar(255). Если это относится к столбцу в таблице пользователей, то 1), скорее всего, гораздо эффективнее добавить столбец целочисленного идентификатора в эту таблицу и использовать его в качестве первичного ключа и в качестве ссылочного столбца в других таблицах; 2) вы используете InnoDB, так почему бы не воспользоваться возможностями внешнего ключа, которые он предлагает?

Учтите, что если вы индексируете по столбцу varchar(n), он обрабатывается как char(n) в индексе, поэтому каждая строка вашего текущего первичного ключа занимает 4 + 128 + 128 = 260 байтов в индексе.

0 голосов
/ 14 сентября 2010

Добавить индекс на user.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...