Как импортировать базу данных, обновлять продукты, которые были изменены, удалять продукты, которые были удалены - PullRequest
5 голосов
/ 27 марта 2012

Я в порядке с базовым MySQL, но это "ПУТЬ НА МОЮ ГОЛОВУ"!

Цели:

  • Импорт базы данных
  • обновить продукты, которые изменились
  • удалить товары, которые были удалены
  • Быстро и качественно

Таблица (ы) базы данных ОГРОМНА, скорость - это проблема.

Не нужно, чтобы MyISAM был бы inoDB быстрее? Каждая база данных будет в уникальной таблице.

Мне дали это как отправную точку к тому, что я пытаюсь сделать:

CREATE TABLE `table` LIKE LiveTable
LOAD DATA INFILE..... INTO `table`
UPDATE `table`  SET delete=1; -- Set the delete field to true  because it will not have been updated
UPDATE `table` INNER JOIN`table`ON `LiveTable.ID`=`table.ID`
SET LiveTable.Col1=table.Col1, LiveTable.Col2=table.Col2….. delete=0
INSERT INTO LiveTable(ID,Col1,Col2,…  delete=0)
SELECT ID,Col1,Col2,...FROM `table`
LEFT JOIN LiveTable 
ON table.ID = LiveTable.ID
WHERE LiveTable.ID IS NULL
DELETE FROM LiveTableWHERE delete = 0
EMPTY TABLE `table`

> CREATE TABLE `product_table`   (
>      `programname` VARCHAR(100) NOT NULL,
>      `name`        VARCHAR(160) NOT NULL,
>      `keywords`    VARCHAR(300) NOT NULL,
>      `description` TEXT NOT NULL,
>      `sku`         VARCHAR(100) NOT NULL,
>      -- This is the only "unique identifier given, none will be duplicates"
>      `price`       DECIMAL(10, 2) NOT NULL,
>      `created`     TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
>      `updatedat`   TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
>      `delete`      TINYINT(4) NOT NULL DEFAULT '0',
>      PRIMARY KEY (`sku`)   ) ENGINE=myisam DEFAULT CHARSET=latin1;
> 
> CREATE TABLE IF NOT EXISTS `temptable` LIKE `product_table`;
> 
> TRUNCATE TABLE `temptable`; -- Remove data from temp table if for some
> reason it has data in it.
> 
> LOAD DATA LOW_PRIORITY LOCAL INFILE "catalog.csv" INTO TABLE
> `temptable`  FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY """"
> LINES TERMINATED BY "\n"  IGNORE 1 LINES (`PROGRAMNAME`, `NAME`,
> `KEYWORDS`, `DESCRIPTION`, `SKU`, `PRICE`);
> 
> 
> UPDATE `temptable` SET    `delete` = 1; -- Set the delete field to
> true UPDATE `temptable` ttable
>        INNER JOIN `product_table` mtable
>          ON ( mtable.sku = ttable.sku ) SET    mtable.programname = ttable.programname,
>        mtable.name = ttable.name,
>        mtable.keywords = ttable.keywords,
>        mtable.description = ttable.description,
>        mtable.sku = ttable.sku,
>        mtable.price = ttable.price,
>        mtable.created = ttable.created,
>        mtable.updatedat = NOW(),-- Set Last Update
>        mtable.delete = 0; -- Set Delete to NO
> 
> -- Not sure what this is for...  I'm LOST at this part...   
> INSERT INTO `product_table` VALUES      (`programname`,
>              `name`,
>              `keywords`,
>              `description`,
>              `sku`,
>              `price`,
>              `created`,
>              `updatedat`,
>              `delete`);
> 
> -- This type of join requires alias as far as I know? 
> SELECT `programname`,
>        `name`,
>        `keywords`,
>        `description`,
>        `sku`,
>        `price`,
>        `created`,
>        `updatedat`,
>        `delete` FROM   `temptable` tmptable
>        LEFT JOIN `product_table` maintbl
>          ON tmptable.sku = maintbl.sku WHERE  maintbl.sku IS NULL;
> 
> DELETE FROM `product_table` WHERE  `delete` = 0;
> 
> TRUNCATE TABLE `temptable`; `` remove all the data from temporary
> table.

Ответы [ 2 ]

4 голосов
/ 10 апреля 2012

Я сам ответил на этот вопрос здесь: https://dba.stackexchange.com/questions/16197/innodb-update-slow-need-a-better-option/16283#16283

Используя информацию, полученную мной здесь, в Интернете и нескольких чатах, я придумал.Источник в Интернете: http://www.softwareprojects.com/resources/programming/t-how-to-use-mysql-fast-load-data-for-updates-1753.html

[DEMO][1] http://sqlfiddle.com/#!2/4ebe0/1

Процесс такой:

Import into a new temp table.
Update The old table information with information in Temp table.
Insert new data into the table. (Real world I'm making a new CSV file and using LOAD INTO for the insert)
delete everything that is no longer in the data feed.
delete the temp table.

На данный момент это самый быстрый процесс.

Дайте мне знать, что вы думаете.

2 голосов
/ 28 марта 2012

InnoDB обычно намного лучше, чем MyISAM, когда таблицы доступны, когда INSERT, UPDATE и DELETE, потому что InnoDB использует блокировку на уровне строки для обновлений, тогда как MyISAM использует блокировку на уровне таблицы.

Это первый шаг.

Второй шаг - отключить все индексы в таблице перед загрузкой данных в таблицу с помощью ALTER TABLE .. DISABLE KEYS, а затем снова включить их после загрузки с помощью ALTER TABLE .. ENABLE KEYS.

Приведенные выше два демонстрируют значительное улучшение производительности.

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

...