SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 30.06.2010 17:09:38

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Копирование большой таблицы

Ситуация такая. Есть таблица, 77 Гб сгенерированная скриптом. В ней нет индексов вообще. Есть в ней одно поле, назовем его keyname, нужно чтобы в этой таблице остались только уникальные записи, но из дублей должна остаться последняя запись, все же остальные удалены.

Самое простое что приходит в голову - делаю еще одну таблицу (t2), аналогичную по структуре, но с уникальным индексом по keyname, затем:

REPLACE INTO t2 SELECT * FROM t1


Так вот, начинается запись, в файловом менеджере видно как растет файл t2.MYD до какого то размера (зависимости от чего либо не заметил, максимум до 1.5 Гб дорос), после чего всё "замирает". Mysql в целом продолжает работать, только в процесс листе появляется некоторое количество запросов со статусом "Copying to tmp table" (эти запросы к другим БД), если процесс не прервать, то количество этих копингов дорастает до того, что mysql перестает принимать соединения, приходится основной процесс снимать.

В чем может быть дело? Может есть какое то более изящное/простое/рабочее решение задачи?

Спасибо заранее

UPD. Забыл сказать - с таблицей этой никто не работает кроме меня.

Отредактированно Shopen (30.06.2010 17:14:18)

Неактивен

 

#2 30.06.2010 17:22:46

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Копирование большой таблицы

В голову приходит только то, что оно не зависает, а начинает считать индекс.
Также может, например, кончаться место (в т.ч. и во временном хранилище).

Насколько часто заполняется эта табличка? Может, сразу сделать индекс и
делать REPLACE в нее? Если одноразовая — нет ли там какой-то неявной сор-
тировки (например, не сортированы ли уже строки по ключу физически)?

Неактивен

 

#3 05.07.2010 14:20:28

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Копирование большой таблицы

paulus написал:

В голову приходит только то, что оно не зависает, а начинает считать индекс.
Также может, например, кончаться место (в т.ч. и во временном хранилище).

место нет, не заканчивается. Насчет индекса - если он и считает его, то очень медленно и без какой либо активности процессором. Я бы оставил его считать себе дальше, но из за набегания висящих запросов в temporary table  вешается все остальное, а там куча важных сервисов.

paulus написал:

Насколько часто заполняется эта табличка? Может, сразу сделать индекс и
делать REPLACE в нее? Если одноразовая — нет ли там какой-то неявной сор-
тировки (например, не сортированы ли уже строки по ключу физически)?

Можно сделать сразу. Но скрипт который генерит эту БД генерит ее _намного_ дольше. Если без индексов время примерно 12 часов, то с индексами время удваивается. Мне изначально казалось, что генерация без индексов + INSERT + SELECT -должна работать гораздо быстрее, я даже не предполагал что наткнусь на такую проблему.

Если никаких других вариантов не придет в голову, придется так и оставить. Насчет сортировки не понял. Таблица делается с нуля.

P.S. Вот думаю, насколько полезно temp мускуля выносить на отдельный диск/массив? На сервере сейчас три райд массива
1. raid1 (75Gb, SAS),
2. raid10 (600Gb, SAS)
3. raid1 (750Gb, SATA).

mysql лежит на 2 массиве, там же и все БД, там же и его temp. 1 массив - система, 3 - файлопомойка, оба загружены весьма слабо. Имеет ли смысл перенести temp и если да, то на какой - побольше или побыстрее smile ?

Неактивен

 

#4 05.07.2010 15:30:10

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Копирование большой таблицы

Если сервер ничем не занимается — значит, он чего-то ждет. Смотрите на блокировки
таблиц / процессов. Может, кто-то HUP серверу кидает, еще что-нибудь.

Неактивен

 

#5 05.07.2010 22:10:38

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Копирование большой таблицы

Да в том то и дело, что ничего подозрительного не наблюдается. Буду дальше наблюдать, либо скриптом геренить вместе с индексами...

Есть еще одна мысль. Почему я вставляю в таблицу без индексов - чтобы скрипт отрабатывал как можно быстрее. Скрипт обрабатывает пачку XML-файлов (тысяч десять в каждом по 10 тысяч записей), соответственно по одному запросу на файл INSERT INTO t1 VALUES (),(),(),()... Что если сделать так: сделать 2 таблицы t1 и t2. Первая без индексов, вторая с.  На t1 повесить триггер на INSERT, который после получения каждого запроса будет лочить 1 таблицу, переносить во вторую (с индексами), после чего первую чистить. Есть ли шанс, что так будет быстрее, чем просто вставлять в одну индексированную?

А что насчет вопроса про райды?

Неактивен

 

#6 06.07.2010 13:12:29

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Копирование большой таблицы

Быстрее, очевидно, не будет, т.к. Вам надо будет писать в два места smile

Про рейды — если у Вас есть регулярные запросы, которые создают
временные таблицы на диске, то имеет смысл переделать запросы так,
чтобы не создавали smile Если переделать не получается (i.e. обработка
всех данных в огромной таблице), то тогда быстрые диски лучше мед-
ленных smile

Неактивен

 

#7 07.07.2010 20:49:09

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Копирование большой таблицы

paulus написал:

Если переделать не получается (i.e. обработка
всех данных в огромной таблице), то тогда быстрые диски лучше медленных smile

Это я понимаю. Тут вопрос немного по другому поводу... сейчас все базы данных и временный каталог расположены на самом быстром райде, но при этом ведь происходит чтение и запись с одного носителя одновременно, поэтому и интересно не стоит ли выносить темп пусть даже на более медленный диск, но отдельный. Поставил process monitor, посмотрел чем занимается mysql (немного прифигел от увиденногоsmile ). Видимо был неправ, считая что процесс висит - он просто долго туда пишет, а изменения размера происходят нечасто. Но пишет он только в t2.MYD и ни в какие временные таблицы, тогда непонятно почему это мешает другие процессам писать в tmp.
Еще заметил странную вещь - почему то одни временные таблицы создаются в temp/, а другие в каталоге data/ (т.е. в корне) а третьи в каталогах самих баз данных. Отчего так, почему mysql не всегда использует указанный ему каталог для временных файлов?

Неактивен

 

#8 07.07.2010 20:59:58

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Копирование большой таблицы

Временные таблицы создаются во временном каталоге. Таблицы, которые потом
заменят основные таблицы, создаются в каталоге с данными (чтобы mv сработал
быстро),  в корне таблицы не создаются.

Неактивен

 

#9 07.07.2010 21:06:53

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Копирование большой таблицы

Ну как, своими глазами наблюдаю:

Код:

Date: 07.07.2010 21:04:30
Thread: 664
Class: File System
Operation: WriteFile
Result: SUCCESS
Path: E:\home\mysql\data\#sql_6dc_13.MYD
Duration: 0.0074455

Неактивен

 

#10 07.07.2010 21:15:41

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Копирование большой таблицы

Не должен бы. А на каком запросе такое?

Неактивен

 

#11 07.07.2010 21:38:55

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Копирование большой таблицы

Вот вроде бы такой:

select SQL_CALC_FOUND_ROWS
        `code`, `date`, `iEnable3x`
      from
        se2_six, se_temp.se2_WordSearchResult_17731_2
      where
        iEnable3x <> '2'
       and iEnable3x <> '1'
       and se2_six.code = se_temp.se2_WordSearchResult_17731_2.nTableRecordKey
      order by date desc
      limit 13950, 25
 


Может mysql в data/ пишет временные таблицы, ну которые CREATE TEMPORARY TABLE? se2_WordSearchResult_17731_2 - как раз временная таблица

Отредактированно Shopen (07.07.2010 21:41:21)

Неактивен

 

#12 07.07.2010 22:34:39

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Копирование большой таблицы

Проверил: временная таблица (create temporary table) у меня создалась в /tmp.
Может, windows-specific?

Неактивен

 

#13 08.08.2010 06:04:34

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Копирование большой таблицы

Тут в процессе занимательной работы с этой БД обнаружил интересный эффект. Есть такой оптимизирующий совет когда делается пачка инсертов в таблицу с инсертами, то нужно делать так


ALTER TABLE tbl DISABLE KEYS
INSERT INTO tbl ....
INSERT INTO tbl ....
INSERT INTO tbl ....
ALTER TABLE tbl ENABLE KEYS
 
для того, чтобы индексы не перестраивались после каждой вставки. Вполне ожидаемо, что если делать вставку множественную:

ALTER TABLE tbl DISABLE KEYS
INSERT INTO tbl VALUES (...),(...),(...),(...)...
ALTER TABLE tbl ENABLE KEYS
 

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

Но оказывается, что если инсерты делаются с использованием ON DUPLICATE KEY UPDATE:

ALTER TABLE tbl DISABLE KEYS
INSERT INTO tbl VALUES (...),(...),(...),(...)... ON DUPLICATE KEY UPDATE ...
ALTER TABLE tbl ENABLE KEYS
 
то отключение индексов вообще запрос замедлит, причем ощутимо, при большом количестве одинаковых вставляемых значений. Интересно это так и должно быть?

Неактивен

 

#14 08.08.2010 20:45:32

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Копирование большой таблицы

Хм. Совсем не очевидное свойство. DISABLE KEYS не выключает уникальные
индексы. Казалось бы, не должно влиять. Есть смысл описать это на bugs.mysql.com
со словами «бага оптимизатора, который считает, что индекса нет».

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson