Simpliest Использовал INSERT ON DUPLICATE, дало нужный результат Блок данных в 200 000 записей обработался где-то за минуты 2, что вполне соответствует коридору который нужно было достичь
ну, это тестировалось на таблице в которой 2 000 000 записей сейчас попробую в таблицу в которой 12 000 000 записей
хм, по времени одинаково получилось.... интересно каким образом работает данная функция.... А вообще ОГРОМНОЕ СПАСИБО очень красивая и эффективная функция
Вобщем фигня это все. на локальной машине у меня Код (Text): +----------+-------------+---------------------------------------------------------------------------- | Query_ID | Duration | Query +----------+-------------+---------------------------------------------------------------------------- | 4 | 0.00028800 | SELECT * FROM tours WHERE `myid`='726d4d70-320e-11df-87f5-00e04d5a6ae2' | 5 | 0.00012500 | explain UPDATE tours SET P=102 WHERE `myid`='726d4d70-320e-11df-87f5-00e04d | 6 | 0.27592900 | UPDATE tours SET P=102 WHERE `myid`='726d4d70-320e-11df-87f5-00e04d5a6ae2' | 7 | 0.01550200 | INSERT INTO tours (myid,P,D,aFCK,aTCK,htlBK,htlCoK, htlCiK,htlRK,htlCN,htlN | 8 | 0.03032400 | INSERT INTO tours (myid,P,D,aFCK,aTCK,htlBK,htlCoK, htlCiK,htlRK,htlCN,htlN | 9 | 0.05457100 | INSERT INTO tours (myid,P,D,aFCK,aTCK,htlBK,htlK,htlCoK, htlCiK,htlRK,htlCN | 10 | 0.00019900 | INSERT INTO tours (myid,P,D,aFCK,aTCK,htlBK,htlK,htlCoK, htlCiK,htlRK,htlCN | 11 | 0.00019300 | INSERT INTO tours (myid,P,D,aFCK,aTCK,htlBK,htlK,htlCoK, htlCiK,htlRK,htlCN | 12 | 0.00018700 | INSERT INTO tours (myid,P,D,aFCK,aTCK,htlBK,htlK,htlCoK, htlCiK,htlRK,htlCN | 13 | 0.00019500 | INSERT INTO tours (myid,P,D,aFCK,aTCK,htlBK,htlK,htlCoK, htlCiK,htlRK,htlCN | 14 | 0.06930200 | INSERT INTO tours (myid,P,D,aFCK,aTCK,htlBK,htlK,htlCoK, htlCiK,htlRK,htlC | 15 | 0.03619900 | select last_insert_id() | 16 | 0.00041100 | select * from tours where myid='726d4d70-320e-11df-87f5-00e04d5a6ae2' | 17 | 0.01595000 | select * from tours where `key`=10000005 | 18 | 30.69585300 | select count(*) from tours +----------+-------------+---------------------------------------------------------------------------- Единственно, обращаю внимание, что быстрее проверить запись по ключу, и потом решать вставлять или апдейтить. 14й запрос это именно INSERT ON DUPLICATE Penegan Сервер выделенный? Где находится БД? какие настройки?
Да, на чем тестировал [sql]CREATE TABLE `tours` ( `myid` char(36) DEFAULT NULL, `P` mediumint(9) NOT NULL, `D` int(11) NOT NULL, `aFCK` mediumint(9) NOT NULL, `aTCK` mediumint(9) NOT NULL, `htlBK` mediumint(9) NOT NULL, `htlK` mediumint(9) NOT NULL, `htlCoK` mediumint(9) NOT NULL, `htlCiK` mediumint(9) NOT NULL, `htlRK` mediumint(9) NOT NULL, `htlCN` text, `htlN` mediumint(9) NOT NULL, `htlD` mediumint(9) NOT NULL, `htlM` mediumint(9) NOT NULL, `roomTK` mediumint(9) NOT NULL, `roomAK` mediumint(9) NOT NULL, `roomNA` mediumint(9) NOT NULL, `roomNC` mediumint(9) NOT NULL, `roomCK` mediumint(9) NOT NULL, `operator` text, `SPO` int(11) NOT NULL, `key` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`key`), UNIQUE KEY `myid` (`myid`), KEY `afck` (`aFCK`), KEY `htlcok` (`htlCoK`), KEY `combined` (`aFCK`,`htlCoK`) ) ENGINE=InnoDB AUTO_INCREMENT=15003001 DEFAULT CHARSET=utf8[/sql] 15млн записей и UUID() в качестве myid уникального значения. измененные настройки сервера Код (Text): key_buffer_size = 192M innodb_buffer_pool_size = 2048M
сервер виртуальный, к настройкам БД, к сожалению, доступа нет Таблица, кстати знакомая Вот таблица на которой я тестировал [sql] CREATE TABLE `tours_389_86` ( `P` smallint(6) NOT NULL, `D` int(11) NOT NULL, `htlBK` tinyint(4) NOT NULL, `htlK` int(11) NOT NULL, `htlRK` int(11) NOT NULL, `htlCN` tinyint(4) NOT NULL, `htlN` tinyint(4) NOT NULL, `roomAK` int(11) NOT NULL, `ourAK` tinyint(4) NOT NULL, `roomCK` int(11) NOT NULL, `operator` tinyint(4) NOT NULL, `SPO` int(11) NOT NULL, `key` varchar(22) NOT NULL, PRIMARY KEY (`key`), KEY `resort` (`htlRK`), KEY `hotel` (`htlK`), KEY `htlBK` (`htlBK`), KEY `P` (`P`), KEY `D` (`D`), KEY `ourAK` (`ourAK`), KEY `htlCN` (`htlCN`), KEY `htlN` (`htlN`) ) ENGINE=MyISAM DEFAULT CHARSET=cp1251; [/sql] Такой как у вас отчет дать не могу, но скорость загрузки предыдущим методом одного блока туров (в блоке 100 -200 тис. записей) могло продолжатся до 2 часов, если много записей, которые нужно обновлять. Вот сейчас блок загрузил, в котором все записи уже есть в таблице, тоесть все должны были обновится. загрузился за минут 10. Можно сделать вывод, что намного эффективнее использовать [sql]INSERT ... ON DUPLICATE KEY UPDATE[/sql] чем PHP: mysql_query("INSERT INTO table VALUES()"); if (preg_match("/.*Duplicate\sentry.+/i", mysql_error())) { mysql_query("UPDATE table SET `fld` = ".$fld.", `fld2`='".$fld."' WHERE `key`=".$id." LIMIT 1"); }
Really? И как вы думаете почему она у меня появилась? Мда, при блочной загрузке... возможно так и есть. Хотя я бы для полноты картины все же попробовал сначала сделать выборку записей по ключу, а затем вставлял только отсутствующие записи, а остальным посылал update. такой отчет делается несколькими строчками PHP: <?php mysql_query('set profiling=1'); // тут запросы $res = mysql_query('show profiles'); while(($row = mysql_fetch_assoc($res))) { var_dump($row); } Правда запросы будут выполнятся несколько медленнее. Поэтому когда он ненужен, его лучше отключать set profiling = 0;
После увеличения нагрузки в несколько десятков раз, пришлось искать метод для обновления данных побыстрее, он как оказалось есть: LOAD DATA ....