Mysql InnoDB оптимизация производительности и индексация - PullRequest
2 голосов
/ 10 июня 2010

У меня есть 2 базы данных, и мне нужно связать информацию между двумя большими таблицами (более 3 миллионов записей в каждой, непрерывно растущих). Первая база данных имеет таблицу «страницы», которая хранит различную информацию о веб-страницах, и включает в себя URL каждой из них. Столбец «URL» является varchar (512) и не имеет индекса.

Во 2-й базе данных есть таблица 'urlHops', определенная как:

CREATE TABLE urlHops ( dest varchar (512) NOT NULL, src varchar (512) DEFAULT NULL, timestamp отметка времени NOT NULL DEFAULT CURRENT_TIMESTAMP, КЛЮЧ dest_key (dest), КЛЮЧ src_key (src) ) ENGINE = InnoDB CHARSET ПО УМОЛЧАНИЮ = latin1

Теперь мне нужно в основном выдавать (эффективно) такие запросы: выберите p.id, p.URL из db1.pages p, db2.urlHops u, где u.src = p.URL и u.dest =?

Сначала я подумал добавить индекс на страницах (URL). Но это очень длинный столбец, и я уже выпускаю много INSERT и UPDATE для одной и той же таблицы (намного больше, чем количество SELECT, которые я бы сделал, используя этот индекс).

Другие возможные решения, которые я подумал: - добавление столбца к страницам, сохранение md5-хеша URL и индексация его; таким образом, я мог бы делать запросы, используя md5 URL, с преимуществом индекса на меньшем столбце. - добавление другой таблицы, которая содержит только идентификатор страницы и URL страницы, индексируя оба столбца. Но это, возможно, пустая трата времени, имеющая только то преимущество, что не замедляет вставки и обновления, которые я выполняю на «страницах».

Я не хочу замедлять вставки и обновления, но в то же время я смогу эффективно выполнять запросы по URL. Любой совет? Моя главная задача - производительность; если это необходимо, тратить место на диске не проблема.

Спасибо, с уважением

Davide

Ответы [ 3 ]

3 голосов
/ 12 июня 2010

Предложение по хешу MD5 у вас очень хорошее - оно задокументировано в High Performance MySQL 2nd Ed. Есть пара трюков, чтобы заставить его работать:

CREATE TABLE urls ( id NOT NULL первичный ключ auto_increment, url varchar (255) не ноль, url_crc32 INT UNSIGNED не нуль, INDEX (url_crc32) );

Выборочные запросы должны выглядеть следующим образом:

ВЫБРАТЬ * ИЗ URL, ГДЕ url = 'http://stackoverflow.com' И url_crc32 = crc32 (' http://stackoverflow.com');

url_crc32 предназначен для работы с индексом, в том числе url в предложении WHERE предназначен для предотвращения коллизий хешей.

Я бы, вероятно, рекомендовал crc32 вместо md5. Будет еще несколько коллизий, но у вас больше шансов разместить весь индекс в памяти.

0 голосов
/ 10 июня 2010

Я бы создал таблицу page_url с целочисленным первичным ключом auto-inc и значением вашего URL. Затем обновите Pages и urlHops для использования page_url.id.

Ваш urlHops станет (dest int, src int, ...)
Ваша таблица страниц заменит URL на pageid.

Индексируйте поле page_url.url, и вам следует идти.

0 голосов
/ 10 июня 2010

Если число страниц на URL-адресах является отношением 1-к-1 и эта таблица имеет уникальный идентификатор (первичный ключ?), Вы можете сохранить это значение идентификатора в полях src и dest в таблице urlHops вместо полного URL-адреса.

Это сделает индексирование и объединение гораздо более эффективным.

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