Является ли использование IN (...) наиболее эффективным способом случайного доступа к таблице MySQL? - PullRequest
1 голос
/ 07 мая 2009

У меня есть таблица с 2,4M + строк и без индексов. Я на 100% уверен, что во всех строках есть один столбец (назовем его id), который уникален и имеет тип VARCHAR(255).

Теперь у меня есть файл приблизительно из 10000 id, и мне нужно вытащить всю строку для каждого.

Является ли использование IN(...) моим лучшим вариантом? Должен ли я добавить индекс?

Я думал о том, чтобы подумать о чем-то вроде этого:

SELECT * FROM archive_table WHERE id IN('id1', 'id2', ... 'idn');

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


Система: MySQL 5.0.45 Таблица: MyISAM

Ответы [ 5 ]

3 голосов
/ 07 мая 2009

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

2 голосов
/ 07 мая 2009

Добавьте индекс в столбце ID и (необязательно) определите его как UNIQUE. Это поможет MySQL быстро найти нужные строки, поскольку индекс содержит идентификатор в отсортированном порядке. Даже если ваш стол был отсортирован, тоже. г. поскольку вы вставляете в порядке возрастания идентификатора, MySQL не знает об этом и всегда будет выполнять полное сканирование таблицы, чтобы найти подходящие записи для ваших запросов.

С индексом, с другой стороны, поиск становится очень простым для сервера. Только если вы запрашиваете действительно очень много строк одновременно (очень длинное предложение IN ()), оптимизатор может решить, что вам нужно более 30% данных - в этом случае он снова вернется к линейному сканированию, чтобы предотвратить чрезмерный поиск диска.

Однако с несколькими миллионами строк это было бы чертовски длинным условием:)

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

0 голосов
/ 08 мая 2009

Да, добавить индекс для обеих таблиц (2,4 млн. И 10 000).

Предполагая, что значение столбца транзакции составляет 10000 строк, значение архива составляет 2,4 миллиона строк, и вы создали индексную переменную архива, которую можно кодировать:

SELECT id
  FROM transaction_table a
 WHERE EXISTS( SELECT *
                 FROM archive_table b
                WHERE a.id = b.id )

Использование предложения EXISTS над JOIN более читабельно и имеет ту же производительность, что и соединение.

0 голосов
/ 07 мая 2009

Исходя из того, что в прошлом нам давали понять наши администраторы баз данных, предложение IN имеет ограничение на количество явных идентификаторов, которые можно указывать в скобках. Мне сообщили, что это не применимо, если вы можете использовать SELECT для подачи списка IN.

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

0 голосов
/ 07 мая 2009

Черт, да, вы должны добавить индекс. Но если идентификатор является «первичным ключом», то он уже является индексом.

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