Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ускорение выборки по большой таблице 
V
    Опции темы
AnemoN
Дата 5.10.2012, 02:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 16.4.2008

Репутация: нет
Всего: нет



Здравствуйте, уважаемые форумчане!

Прошу вашей консультации по следующей ситуации.

Есть программа, получающая на некотором этапе массив ссылок (как правило около 30), которые необходимо обработать и записать результат в таблицу:

Код

CREATE TABLE IF NOT EXISTS `table`
(
  `iid` int(10) unsigned NOT NULL,
  `hid` int(10) unsigned NOT NULL,
  `url` text,
  `found`  int(10) unsigned NOT NULL,
  KEY (`iid`),
  UNIQUE KEY `iid-hid` (`iid`, `hid`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;


Однако перед этим необходимо перед началом обработки удалить из массива те ссылки, которые уже есть в таблице (поле url)
Рассчитываю, что это значительно увеличит производительность программы.

Беда в том, что сделать выборку
Код

SELECT iid FROM `table` WHERE url IN ('url_1', 'url_2', ..., 'url_n')

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

Единственная идея, которая приходит на ум — это добавить "индексное" поле с MD5-хешами ссылок
Код

`url_hash` varchar(32) NOT NULL DEFAULT ''

и делать выборку по нему:
Код

SELECT iid FROM `table` WHERE url_hash IN ('url_hash_1', 'url_hash_2', ..., 'url_hash_n')


Возможно есть более эффективные способы?

Буду благодарен за любую помощь.

Это сообщение отредактировал(а) AnemoN - 5.10.2012, 11:16
PM MAIL   Вверх
skyboy
Дата 5.10.2012, 08:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(AnemoN @  5.10.2012,  01:37 Найти цитируемый пост)
Однако перед этим необходимо перед началом обработки удалить из массива те ссылки, которые уже есть в таблице (поле url)

то есть, у тебя URL выступает уникальным ключом, так?
тогда и объяви его уникальным ключом.
и используй конструкцию
Код

INSERT … /*либо просто вставляешь все значения*/ 
ON DUPLICATE KEY UPDATE = … 
/*в случае, если URL такой есть  — перезаписываешь остальные поля*/

PM MAIL   Вверх
AnemoN
Дата 5.10.2012, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 16.4.2008

Репутация: нет
Всего: нет



Цитата(skyboy @  5.10.2012,  08:31 Найти цитируемый пост)
то есть, у тебя URL выступает уникальным ключом, так?

Нет, url'ы могут быть одинаковыми

INSERT вообще не получится сделать, т.к. для этого нужно сначала загрузить кучу данных и обработать их (они записываются в другую таблицу, связанную с текущей по iid), чего я и пытаюсь избежать.

Извините за несколько сумбурное объяснение, стараюсь как могу  smile 
PM MAIL   Вверх
Akina
Дата 5.10.2012, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(AnemoN @  5.10.2012,  03:37 Найти цитируемый пост)
в таблице порядка 10.000.000 записей, и если сотня-другая потоков станет делать такие выборки по text-полю, пусть и в критической секции, но к добру это не приведет.

Если поле проиндексировать (сейчас, без индекса, сервер офигеет и от трёх потоков) - станет легче.
Если использовать хэш с индексом по нему - серверу станет ещё легче. 
Только:

1) MD5 не бывает короче 32 символов. Зачем VARCHAR? просто CHAR;
2) MD5 всё равно текстовый. Используйте хэширование в UNSIGNED INT, числа обрабатываются быстрее строк, а 4 миллиардов при 10 миллионах записей вполне достаточно;
3) В запросе-выборки по хэшам получайте не только IID, но и сам URL, и проверяйте - а вдруг коллизия?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
AnemoN
Дата 5.10.2012, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 16.4.2008

Репутация: нет
Всего: нет



Спасибо!

Действительно, замена MD5 на CRC32 в uint - это то, что нужно.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0840 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.