Обновление таблиц, как оптимальнее?

_RVK_

Новичок
Обновление таблиц, как оптимальнее?

Вопрос в следующем.
Идет обновление из XML. Для этого написан скрипт, который рекурсивно проходит по дереву, и обновляет 4 таблицы. Сейчас тупо удаляются данные, а потом, по мере прохода по дереву, вставляются обновленные данные. Естественно в реальной системе так быть не может, т.к обновление занимает несколько минут, и в это время сайт неработоспособен. Ищу наилучший выход.
Понятно что нужно создавать временные таблицы, добавлять данные в них, а потом просто менять местами. Вот тут и вопрос. Я вижу несколько способов:

Первый:
1. Создаем временную таблицу CREATE TEMPORARY TABLE tmp ...
2. Добавляем данные. INSERT INTO tmp...
3. Удаляем данные из основной. DELETE FROM real_table...
4. INSERT INTO real_table SELECT * FROM tmp...

Недостатки:
1. Время на удаление данных.
2. Время на добавление данных.
Соответственно некоторое время данные недоступны. При моих ~20000 записей это несколько секунд, но если данных будет 20000000...

Второй:

1. -
2. -
3. Удаляем основную DROP TABLE real_table...
4. Создаем заново CREATE TABLE real_table SELECT * FROM tmp

Недостатки:
1. Некоторое время таблицы вообще нет. Хотя удалить таблицу ИМХО быстрее чем данные из неё.
2. Время на создание таблицы и добавление данных.

Третий:

1.-
2.-
3. Переименовываем временную таблицу в новую. ALTER TABLE tmp RENAME real_table

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

Ну и сам вопрос, как действительно нужно делать?
 

Кром

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

_RVK_

Новичок
Автор оригинала: Кром
Ты сделай ряд дублирующих таблиц. Сначала обновляй одну группу, переключай индикатор, который указывает на ту группу, где произошло последнее обновление, и начитай обновлять другую группу таблиц.
А подробнее, плиз, как это физически реализовать? Типа хранить в какой то таблице имена таблиц, которые на данный момент являются самыми новыми?
 

Кром

Новичок
>Типа хранить в какой то таблице имена таблиц, которые на данный момент являются самыми новыми?

Как хочешь. Можно например создать таблицу, в которую записывать время обновления и номер группы таблиц.
А уж имена таблиц можешь брать откуда хочешь. Из базы или из скриптов.
 

_RVK_

Новичок
Да, действительно не подумал :) Так что все рассмотренные мной варианты бред? Так (или примерно так) никто не делает?
 

Кром

Новичок
>Так (или примерно так) никто не делает?

А зачем так делать если можно сделать лучше? :)
 

ForJest

- свежая кровь
Я бы присоветовал по твоему сценарию:
1. Создаем временную таблицу CREATE TEMPORARY TABLE tmp ...
2. Добавляем данные. INSERT INTO tmp...

3. REPLACE INTO real_table SELECT * FROM tmp...

Сейчас тупо удаляются данные, а потом, по мере прохода по дереву, вставляются обновленные данные. Естественно в реальной системе так быть не может, т.к обновление занимает несколько минут, и в это время сайт неработоспособен.
Но вообще можно даже сделать проще - во время обхода
делать вместо DELETE + INSERT
REPLACE DELAYED, что позволит накопить несколько изменений и потом их применить сразу.

Про синтаксис всего этого рекомендую почитать в мане. Один важный нотис - что у таблиц должен быть PRIMARY KEY. Вообще удаление/вставка выполняются довольно быстро, если есть индексы. Может быть дело в том, что их нет?
 

_RVK_

Новичок
ForJest
Вообще удаление/вставка выполняются довольно быстро, если есть индексы
Всегда казалось что индексы как раз и тормозят такие операции, те тратится время на создание индекса.
у таблиц должен быть PRIMARY KEY
Он то есть, иначе по чем связывать все 4 таблицы. Но данные грузятся из 1c, там есть свой id у данных, но он не соответствует томц что в моей базе, и может меняться без предупреждения. Соответственно лучше все данные каждый раз обновлять заново, так проблем меньше. Поэтому вариант Крома, это лучшее решение.

-~{}~ 11.08.04 17:07:

А тормоза в парсинге XML а не в операциях с БД, но это не играет большой роли, тк все выполняется в фоне.
 

ForJest

- свежая кровь
Diesel
Если ты выполняешь удаление по одной записи, то индексы существенно помогут в этом.
Ну а о тонкостях 1C я не знал на момент написания поста, так что советовал исходя из других предположений.
 
Сверху