Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Что лучше: много однострочных или один многострочный запрос INSERT?
 
 автор: sav   (16.01.2008 в 18:26)   письмо автору
 
 

Сделать так:

<?php
$array 
= array(много данных);
foreach(
$array as $val)
{
 
mysql_query("insert into table values($val)");
}
?>

или

<?php
$array 
= array(много данных);
$insert 'insert into table values';
foreach(
$array as $val)
{
 
$insert .="('$val'),";
}
mysql_query($insert);
?>

т.е много запросов делать или один но большой?

   
 
 автор: AVS   (16.01.2008 в 19:58)   письмо автору
 
   для: sav   (16.01.2008 в 18:26)
 

Думаю лучше сделать один, но большой запрос. По идеи скрипт должен быстрее отработать. А вообще попробуй засеч время исполнения скрипта.


<?php
$time
=microtime(1); 
$array = array(много данных); 
$insert 'insert into table values'
foreach(
$array as $val

 
$insert .="('$val'),"

mysql_query($insert);
echo (
microtime(1)-$time); 
?>

   
 
 автор: elenaki   (16.01.2008 в 20:22)   письмо автору
 
   для: AVS   (16.01.2008 в 19:58)
 

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

   
 
 автор: tAleks   (16.01.2008 в 20:27)   письмо автору
 
   для: elenaki   (16.01.2008 в 20:22)
 

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

   
 
 автор: elenaki   (16.01.2008 в 20:55)   письмо автору
 
   для: tAleks   (16.01.2008 в 20:27)
 

скажет - "ошибка в строке 1". а там ВСЕ в строке 1! я пробовала и одним запросом, но пришла к выводу, что лучше на каждую строку свой запрос. когда получаешь данные по почте от неподготовленного юзера, там может быть все, что угодно. самая частая ошибка - таб в ячейке и в csv все ячейки сдвигаются. или вообще какие-то нечитаемые символы (csv делали не в Excel, а в другом приложении). да много всего может быть. если б не было такого печального опыта, я бы не реагировала.

   
 
 автор: AVS   (16.01.2008 в 20:32)   письмо автору
 
   для: elenaki   (16.01.2008 в 20:22)
 

elenaki: Ну не знаю. Перед построением запроса делаем mysql_real_escape_string() для вставляемых данных. Данные в запросе заключаем к кавычки. Тип не важен. MySQL сам выполнит преодразования типов. Если число в кавычках, это нормально, а вот строка без кавычек это error! А если данных для вставки действительно много? И взаимодействие с базой плохое (по скорости)? Тогда PHP остановит скрипт по timeout.

   
 
 автор: Trianon   (16.01.2008 в 22:35)   письмо автору
 
   для: elenaki   (16.01.2008 в 20:22)
 

В MySQL запрещенных символов не бывает в принципе.
Иначе нельзя было бы двоичные файлы в таблицы вносить (те же картинки и прочее).
А значит сгенерировать корректный запрос можно всегда.
Писать весь объем данных в один запрос, конечно же, не стоит.
Но выбрать разумное количество записей - более чем полезно. Это изрядно (в некоторых случаях в десятки раз) ускоряет процесс вставки.

   
 
 автор: AVS   (16.01.2008 в 23:07)   письмо автору
 
   для: Trianon   (16.01.2008 в 22:35)
 

>А значит сгенерировать корректный запрос можно всегда.

Я этого не отрицаю. Но существует понятие "синтаксическая ошибка". Строка содержит кавычку - будет ошибка если сама строка взята в кавычки. Имя таблицы содержит обратную кавычку и мы используем обратные кавычки для обозначения этих имен - ошибка. Это надо учитывать всегда. Особенно при написании своей системы дампа базы данных (например) или другого скрипта, генерирующего запросы.

   
 
 автор: Trianon   (16.01.2008 в 23:26)   письмо автору
 
   для: AVS   (16.01.2008 в 23:07)
 

>>А значит сгенерировать корректный запрос можно всегда.
>Я этого не отрицаю. Но существует понятие "синтаксическая ошибка".
>Строка содержит кавычку - будет ошибка если сама строка взята в кавычки.

Не будет, если правила лексики языка будут соблюдены.
insert into `O``relly` (id, `mc``robbins`)  VALUES (1, "O\"Henry");


>Имя таблицы содержит обратную кавычку и мы используем обратные кавычки для обозначения этих имен - ошибка.
Не будет, если правила лексики языка будут соблюдены.
 CREATE TABLE `O``relly` (
`id``row` INT NOT NULL ,
`mc``robbins` VARCHAR( 20 ) NOT NULL
) ENGINE = MYISAM 



>Это надо учитывать всегда.
>Особенно при написании своей системы дампа базы данных (например) или другого скрипта, >генерирующего запросы.

На данном уровне это не синтаксическая ошибка. Это ошибка в алгоритме. То есть логическая.

   
 
 автор: AVS   (17.01.2008 в 00:15)   письмо автору
 
   для: Trianon   (16.01.2008 в 23:26)
 

Согласен. Именно это я и имел в виду.

   
 
 автор: cheops   (17.01.2008 в 02:34)   письмо автору
 
   для: sav   (16.01.2008 в 18:26)
 

Если объём данных в массиве $array не больше max_allowed_packet (по умолчанию 2 Мб), то лучше использовать второй вариант.

   
 
 автор: sav   (17.01.2008 в 12:19)   письмо автору
 
   для: cheops   (17.01.2008 в 02:34)
 

размер можно выбирать я делаю так например текстовый файл весит 5 мб

<?php
fopen
('text.txt'"r");
$part_size 104857;
while(!
feof($handle))
{
    
$buffer .= fgets($handle4096);
    if(
ftell($handle) >= $part_size)
    {
        
//когда размер строки 104857 байт парсю её и записываю в БД
        
$this->parser($buffer);
        
$buffer '';
        
$part_size += 104857;
    }
    
$i++;
}
//тут пишем оставшуюся часть файла
$this->parser($buffer);
fclose($handle);
?>


при таком раскладе какой размер части будет оптимальным?

   
 
 автор: Trianon   (17.01.2008 в 23:23)   письмо автору
 
   для: sav   (17.01.2008 в 12:19)
 

а если $this->parser не съел ровно 104857 байт? Остаток выкидываете?

Дальше. На первом этапе Вы обрабатываете (примерно) 100 Кб
на втором - 200 Кб на третьем 300 и т.д.?

   
 
 автор: sav   (18.01.2008 в 17:59)   письмо автору
 
   для: Trianon   (17.01.2008 в 23:23)
 

>а если $this->parser не съел ровно 104857 байт? Остаток выкидываете?
остаток тоже обрабатывается когда буфер уже не получается 104857 байт

>Дальше. На первом этапе Вы обрабатываете (примерно) 100 Кб
>на втором - 200 Кб на третьем 300 и т.д.?
нет. каждый раз обрабатывается по 104857 байт, ftell($handle) при каждом круге увеличивается, поэтому я увеличиваю значение $part_size += 104857;
вопрос в том что какой оптимальный размер части для обработки?

   
 
 автор: Trianon   (18.01.2008 в 21:50)   письмо автору
 
   для: sav   (18.01.2008 в 17:59)
 

>>а если $this->parser не съел ровно 104857 байт? Остаток выкидываете?
>остаток тоже обрабатывается когда буфер уже не получается 104857 байт

Я в Вашем коде вижу иное. $buffer = ''; безусловно.



>нет. каждый раз обрабатывается по 104857 байт, ftell($handle) при каждом круге увеличивается, поэтому я увеличиваю значение $part_size += 104857;

Верно, тут я проглядел ftell()

>вопрос в том что какой оптимальный размер части для обработки?

Для любого подобного процесса оптимальный размер буфера может быть определен опытным путем.

Для этого выполняют замеры производительности при размере буфера 1Кб 2Кб 4Кб 8Кб и т.д.
С некоторого момента производительность (в Кб/сек), как функция от размера буфера, перестает расти, и начинает ассимптотически приближаться к некоторой константе. Где-то в этой точке (где производная роста становится меньше единицы) имеет смысл остановиться, дабы не тратить зря ресурсы.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования