Мысли о выполнении SQL-запросов

carte_noire

Новичок
Здравствуйте.
Сегодня я писал код, который получал данные из mySQL, представлял их в виде массива. Казалось бы все так обычно.
Потом я смотрел эти данные и менял их, в общем обрабатывал как-то. А после этого мне нужно было сохранить их обратно. То есть сделать UPDATE. И вот я задумался, а как? Быдлокодерская сущность подсказывала:
PHP:
//Псведокод
foreach($items as $item) {
  query(UPDATE table SET column_1=$item['some_value'] WHERE id=$item['elem_id']);
}

Но у меня 100 элементов. Это получается 100 апдейтов. И я подумал, что может быть есть способ сериализовать массив, засунуть его в строку и передать на сервер, а там распаковать его и провести какие-то действия. То есть как бы выполнить такой запрос, который сам скомбинирует пары id->value и выполнит нужный запрос, только инкапсулировать все это на сервере, понимаете?
То есть выполнить всего один запрос вида:
Код:
UPDATE table SET array('value') WHERE id=array('id')

Понимаете?
 
Ну да, это то, что я искал...
Так и напишем
Код:
multi(UPDATE $item[1]; UPDATE $item[2]; .... UPDATE $item[10000];)

Вы не поняли. Я хочу как-то накладывать программные структуры данных на SQL. Это что-то вроде ORM-a, только реализацию я хочу вынести в SQL-сервер. Хранимая процедура? Дайте еще умных слов....
 
Для начала определись, чего ты хочешь.
А то тебя, как щеночка на льду, сразу во все стороны тянет. И хранимые процедуры тебе хочется, и запросов сэкономить, и орм (при этом остаётся загадкой - что именно ты собираешься мапить и куда, этим своим мультизапросом).

Для начала ответь себе на вопрос, чем плох быдлокодерский вариант.
 
Для начала ответь себе на вопрос, чем плох быдлокодерский вариант.
Вот! Я тоже себе так говорю... По сути, все так делают и ничего - живы, здоровы...
Но в последнее время мне кажется, что многое из того, что я делаю на PHP - тупо и банально.
Недавно писал парсер, который запускался по крону и сохранял распарсенное в текстовый файл для ускорения загрузки страницы... Кэш такой своеобразный получился...
Все довольны, а мне кажется, что там говнокод... Перевел все на классы для успокоения... Так теперь кажется, что у меня быдло-ООП... И я перевел на классы просто ради перевода на классы, но все при этом осталось так же, только ф-ии вызываются через "->". Тупо обертку написал...
Но плюс все-таки появился, я обеспечил "гранулярность"(из книжки по алгоритмам) программы, то есть разбил ее на слабосвязанные части, которые выполняются друг за другом. Вначале выполняешь все HTTP-запросы для получения сырого контента, потом парсишь весь контент и формируешь из него структуры языка, в общем конвейер такой..

О чем это я? Ах да...
На фоне того, что 100 UPDATE-ов в цикле это тупо и скучно я решил узнать, как можно за 1 запрос записать массив значений. То есть передать в MySQL не строки, а массив строк. А обработку этого массива строка возложить на mysql-daemon.
Сегодня мне пришла хорошая аналогия - то, что я хочу, можно описать как векторный процессор (http://ru.wikipedia.org/wiki/Векторный_процессор).

Он может выполнять однотипные операции с векторами за 1 команду. Ведь по сути, действия в цикле они однотипны. Просто меняется значения и все.
Вот я и хочу оперировать с массивами... То есть создать такую абстракцию, что бы дать в запрос два массива вида id => value. А сервер уже сам с ними разбирается и сопоставляет одно к другому.
Надеюсь, все поняли, о чем я...
UPD.
Разумеется, в запросах мы можем оперировать только строками, поэтому предварительно структуры языка нужно сериализовать... Думаю JSON подойдет... Главное, что бы потом из этого JSONа можно было получить исходные структуры на mysql-сервере...
 
Последнее редактирование:
carte_noire, есть ещё вариант: DELETE + INSERT в одной транзакции, при условии, что в запросе DELETE все строки группируются по какому-нибудь признаку (внешний ключ, например, или общее значение в специальном поле), а INSERT будет "собран" в цикле и представлять из себя один запрос. Первым запросом сбросятся все "устаревшие" записи, вторым запросом вставятся "обновлённые" записи.
 
Возможно, тут подойдет insert (), () ... on duplicate key update field1 = VALUES.field1, field2 = VALUES.field2
 
@AmdY , да у меня не такие большие познания в SQL... Ладно...
"Надо уметь находить информацию, что бы не задавать глупых вопросов". Всем мир, всем спасибо... Шлак этот потрите нафиг.
 
На фоне того, что 100 UPDATE-ов в цикле это тупо и скучно я решил узнать, как можно за 1 запрос записать массив значений. То есть передать в MySQL не строки, а массив строк. А обработку этого массива строка возложить на mysql-daemon.

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

##Ушел пить чай##
 
  • Like
Реакции: AmdY
На самом деле, как я уже говорил, тебе надо определиться с тем, чего ты хочешь.
Сам по себе одномоментный запрос ничего не даёт.

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

Но вообще, SQL - по факту атомарный язык. И я бы на твоём месте не занимался преждевременной оптимизацией, а сделал поддержку единственного апдейта, а для множественных завернул их в цикл и транзакцию.
 
PHP:
foreach($res as $item) {
   $sql = "UPDATE `posts` SET `post_content`='". $change_post ."' WHERE `ID`='".$item['ID']."'";
   $dbh->query($sql);
}
Вот мой код. Адекватно? Задача была такая - выбрать все страницы и заменить в них ссылки (<a></a>) по шаблону.
Я их выбрал, заменил контент... Теперь вот так записываю обратно.
Ну вот тут ко мне и пришла эта мысль про один супер-запрос, который без цикла все сделает.
 
Неадекватно. Судя по всему, используется PDO, так, простите, и используйте уже его, а не доморощенные "конструкторы" запросов из обрезков строк.
prepare запроса перед циклом, execute в цикле. Реально выиграть от 2% до 10% времени CPU, в зависимости от количества вставляемых данных.
 
Сверху