Создание индекса на таблицу с большим количеством записей. Обмен данными.

ForJest

- свежая кровь
Создание индекса на таблицу с большим количеством записей. Обмен данными.

В общем ситуация.
Есть буфферная таблица
[sql]
CREATE TABLE buffer (
hash int(11) NOT NULL default '0',
word char(31) NOT NULL default ''
) TYPE=MyISAM;
[/sql]
В ней от 15 до 100 миллионов записей. 15 000 000 - 100 000 000 записей.
И есть "рабочая" таблица куда нужно добавить данные из буфферной
[sql]
CREATE TABLE hash_word (
hash int(11) NOT NULL default '0',
word char(31) NOT NULL default '',
PRIMARY KEY (hash),
UNIQUE KEY word (word)
) TYPE=MyISAM;
[/sql]
Отличается она, как видно из описания лишь наличием уникальных ключей. И в ней содержится гораздо меньшее количество записей - допустим до 500 000.
Буфферная таблица нужна, чтобы не тратить время на создание индекса в процессе работы - просто накопление данных.
--------------------------------------------
Теперь вопрос. Какой способ займёт меньше времени для добавления данных из таблицы buffer в таблицу hash_word?
1. Делаем
[sql]
INSERT INTO hash_word SELECT * FROM buffer;
[/sql]
2. Делаем
[sql]
ALTER TABLE hash_word DISABLE KEYS;
INSERT INTO hash_word SELECT * FROM buffer;
ALTER TABLE hash_word ENABLE KEYS;
[/sql]
3. Или, учитывая что hash_word содержит 1-6% данных от буфферной таблицы - просто подменим её.
[sql]
INSERT INTO buffer SELECT * FROM hash_word;
ALTER TABLE buffer ADD PRIMARY KEY (hash), ADD UNIQUE (word);
DROP TABLE hash_word;
ALTER TABLE buffer RENAME hash_word;
[/sql]

Кто что думает по этому поводу? Я слышал ещё способ какой-то через myisamchk хитрый, но не помню подробностей.
Поделитесь пожалуйста информацией.
 

camka

не самка
А ты пробовал все эти три способа? Замерял время работы каждого?
 

ForJest

- свежая кровь
camka
Нет я не пробовал. Я спрашиваю у людей знающих.
Пока что я попробовал способ №2, т.к. смутно помню его из мануала.
Получилось в принципе в приемлемое время :).
Ну разве что там нужно INSERT IGNORE вместо просто INSERT.
Накопится ещё данных - будем посмотреть - у меня аналогичная задача, только в принимающей таблице 20 млн записей. Поэтому найти быстрый способ задача критичная.
 

camka

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

ForJest

- свежая кровь
camka
Теоретически я не берусь предполагать :). Мне нужен практический совет :).
Ну хотя пожалуй на маленькой тестовой табличке в пол миллиона можно будет попробовать оттестить.
 

ONK

Пассивист PHPСluba
ForJest, ты бы протестировал, а потом рассказал нам о результатах?
 

Necromant

Новичок
Как бы , ни было , но
[sql]
DROP TABLE _hash_word;

CREATE TABLE _hash_word(
hash int( 11 ) NOT NULL default '0',
word char( 31 ) NOT NULL default '',
PRIMARY KEY ( hash ) ,
UNIQUE KEY word( word )
) TYPE = MYISAM ;

INSERT INTO _hash_word
SELECT * FROM hash_word;

INSERT INTO _hash_word
SELECT DISTINCT(*) FROM buffer;

DROP TABLE hash_word;

ALTER TABLE _hash_word RENAME hash_word;
[/sql]
Т.е. все опаерации производятся во временной таблице, после чего т.к. операции RENAME происодят очень быстро . hash_word подменяется временой таблицей _hash_word
 

ONK

Пассивист PHPСluba
Necromant, ты просто не понял суть проблемы...
А про то, что пример дохлый, а если его оживить то работать он будет медленнее всего я ничего не говорю (почти).
 

Necromant

Новичок
Есть , таблица А , с котрой раюотает система , чтоб не нарушать работу, все измения проводятся в врменй таблице Б , после чего таблица А подменяется Б.
ONK я знаю, что медлено, но абсолютно не заметно и быстро для внешних приложений работающих с таблицей А.
 
Сверху