MySQL индекс скорости - PullRequest
       2

MySQL индекс скорости

1 голос
/ 09 декабря 2011

У меня есть таблица, которая будет в среднем около 2 - 5 миллионов строк.У него есть первичный ключ / индекс с именем «инструкция_идей» и другое индексированное поле с именем «режим».теперь 'инструкция_ид', конечно, уникальна, так как это первичный ключ, но "режим" будет только одним из 3 различных значений.Запрос, который я выполняю все время:

SELECT * FROM tablename WHERE mode = 'value1' ORDER BY instruction_id LIMIT 50

В настоящее время это занимает около 25 секунд (> 1 секунда недопустимо долго), но сейчас только 600K строк, поэтому с ростом таблицы будет хуже.Поможет ли индексация по-другому?Если я внесу в указатель инструкцию и режим вместе, это будет иметь значение?Если бы я каким-то образом смог естественным образом упорядочить таблицу по инструкции_, чтобы мне не нужно было запрашивать порядок, это было бы другим способом, но я не знаю, как это сделать ... Любая помощь будет отличной.

Ответы [ 4 ]

5 голосов
/ 09 декабря 2011

Вы должны попробовать индексировать (mode, инструкция_ид) в указанном порядке.

Причина этого индекса в том, что он создает такой индекс

mode  instruction_id
A     1
A     3
A     4
A     5
A     10
A     11
B     2
B     8
B     12
B     13
B     14
C     6
C     7
C     9
C     15
C     16
C     17

Если вы ищетеВ режиме B сервер sql может выполнять поиск по индексу с помощью бинарного поиска в режиме, пока не найдет первый B, а затем может просто вывести следующие n строки.Это было бы очень быстро, примерно 22 сравнения для строк 4M.

Всегда используйте ORDER BY, если ожидаете, что результат будет упорядочен, независимо от того, как хранятся данные.Механизм запросов может выбрать план запроса, который выводит строки в другом порядке, чем порядок PK (возможно, не в таких простых случаях, как этот, но в целом).

3 голосов
/ 10 декабря 2011

Вы должны проверить следующие ссылки, относящиеся к кластеризованным индексам innodb

Затем создайте что-нибудь из вашей схемы в соответствии с:

drop table if exists instruction_modes;
create table instruction_modes
(
mode_id smallint unsigned not null,
instruction_id int unsigned not null,
primary key (mode_id, instruction_id), -- note the clustered composite PK order !
unique key (instruction_id)
)
engine = innodb;

Производительность холодного (перезапуска MySQL) при запуске следующим образом:

select count(*) from instruction_modes;
+----------+
| count(*) |
+----------+
|  6000000 |
+----------+
1 row in set (2.54 sec)

select distinct mode_id from instruction_modes;
+---------+
| mode_id |
+---------+
|       1 |
|       2 |
|       3 |
+---------+
3 rows in set (0.06 sec)

select * from instruction_modes where mode_id = 2 order by instruction_id limit 10;
+---------+----------------+
| mode_id | instruction_id |
+---------+----------------+
|       2 |              2 |
|       2 |              3 |
|       2 |              4 |
|       2 |              5 |
|       2 |              6 |
|       2 |              9 |
|       2 |             14 |
|       2 |             25 |
|       2 |             28 |
|       2 |             32 |
+---------+----------------+
10 rows in set (0.04 sec)

0,04 секунды холодно кажется довольно производительным.

Надеюсь, это поможет:)

2 голосов
/ 09 декабря 2011

Вот одно из возможных решений:

ALTER TABLE `tablename` ADD UNIQUE  (`mode`, instruction_id);

Тогда:

SELECT A.* FROM tablename A JOIN (
     SELECT instruction_id FROM tablename 
     WHERE mode = 'value1' 
     ORDER BY instruction_id LIMIT 50
     ) B 
ON (A.instruction_id = B.instruction_id);

Я обнаружил, что для больших таблиц такой подход работает хорошо для скорости, поскольку подзапрос должен использовать толькоиндекс.

Я использую аналогичный запрос к таблице с> 100 млн записей, и он возвращает результаты через 1-2 секунды.

1 голос
/ 09 декабря 2011

Является ли 'mode' символьным полем?Если он когда-либо будет содержать только 3 возможных значения, это звучит так, как будто вы должны сделать это полем enum, которое будет возвращать вам текстовую строку, но хранится внутри как число.

Вы также должны следовать совету Альбинана индексирование, которое принесет вам дальнейшую пользу.

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