Автор Тема: php+SQLite / Максимальная длина оператора SQL [решено]  (Прочитано 1291 раз)

Оффлайн berkut_174

  • Мастер
  • ***
  • Сообщений: 7 152
Всем привет!

Использую такой запрос для вставки в БД:
INSERT INTO table1 (id, value) VALUES ('1', 'value1'), ('2','value2'), ('3','value3'), ...VALUES получаю из массива. Таких VALUES может быть очень много, вплоть до нескольких 10 т.
Очевидно, у меня возникает проблема при попытке выполнить такой запрос.
См. про лимиты. Похоже мой случай это -- SQLITE_MAX_SQL_LENGTH.
По умолчанию должно быть 1 000 000, но написано, там же, что можно увеличить до 1 073 741 824.

Вопрос:
1. как увеличить это значение ?
2. а есть ли смысл ? может как-то строку разбить лучше будет ? но как ?

Заранее спасибо за советы.
« Последнее редактирование: 30.10.2016 13:03:41 от Skull »
Сноси Винду, переходи на Линукс ! :)

Оффлайн berkut_174

  • Мастер
  • ***
  • Сообщений: 7 152
Хм... сейчас вывел длину строки, кот. использую в запросе, получилось всего 176103.
Почему же тогда не отправляется в БД ???
Сноси Винду, переходи на Линукс ! :)

Оффлайн berkut_174

  • Мастер
  • ***
  • Сообщений: 7 152
В общем в моём случае ограничение установлено в 150000.
Только где это прописано и как поменять, я не в курсе.
Буду рад, если кто подскажет...
Сноси Винду, переходи на Линукс ! :)

Оффлайн ruslandh

  • Поспешай не торопясь !
  • Модератор глобальный
  • *****
  • Сообщений: 32 361
  • Учиться .... Телепатами не рождаются, ими ....
1 А какая версия sqlite используется?

Установил sqlite3-doc и смотрю:

/usr/share/doc/sqlite3/html/c3ref/limit.html

Что соответствует онлайн документации:
https://www.sqlite.org/c3ref/limit.html
« Последнее редактирование: 07.01.2016 19:01:08 от ruslandh »

Оффлайн berkut_174

  • Мастер
  • ***
  • Сообщений: 7 152
Установлено:
$ rpm -qa|grep sqlite
sqlite3-3.7.15.2-alt1
php5-pdo_sqlite-5.5.24.20150415-alt0.M70P.1
libsqlite3-3.7.15.2-alt1
Создаю БД так:
$db = new PDO('sqlite:base.db');Выполняю запрос так:
$sql = "INSERT INTO table1 (id, value) VALUES ('1', 'value1'), ('2','value2'), ('3','value3'), ...";
$db->query($sql);
Длину строки см. через strlen. Когда превышает значение в 150000, данные не уходят в БД.
Сноси Винду, переходи на Линукс ! :)

Оффлайн berkut_174

  • Мастер
  • ***
  • Сообщений: 7 152
Я вообще ассоциативный массив в БД записать хочу.
Сейчас пока разделил порциями, но выглядит очень костыльно...
Сноси Винду, переходи на Линукс ! :)

Оффлайн ruslandh

  • Поспешай не торопясь !
  • Модератор глобальный
  • *****
  • Сообщений: 32 361
  • Учиться .... Телепатами не рождаются, ими ....
А не может это быть ограничением php ?

Оффлайн berkut_174

  • Мастер
  • ***
  • Сообщений: 7 152
А не может это быть ограничением php ?
Да кто его знает, я никаких настроек найти не могу...
Поиски в сети тоже безуспешны.
Сноси Винду, переходи на Линукс ! :)

Оффлайн berkut_174

  • Мастер
  • ***
  • Сообщений: 7 152
К сожалению, так и не удалось найти где хранятся эти лимиты и как их обойти...
Вот что-то мельком про Drupal https://www.drupal.org/node/2031261 и патч для обхода лимита SQLITE_MAX_VARIABLE_NUMBER, который мне как раз сейчас нужно обойти...
Совершенно не знаю как поступить... вроде разработчики наоборот "настоятельно" рекомендуют использовать именно prepare для подготовки запроса, но ограничение в 999 плейсхолдеров никуда не годится, мне бы хотя бы до 20 т. поднять... нужно большой массив отправить в базу, я и так его уже делю на блоки по 500 записей... если делать меньше, уж очень долго вставляются данные.
Сноси Винду, переходи на Линукс ! :)

Оффлайн Dmytro

  • Мастер
  • ***
  • Сообщений: 1 001
По Вашей ссылке написано (выделил важное):
Цитировать
You can raise or lower this value at compile-time using a command-line option like this:

    -DSQLITE_MAX_LENGTH=123456789

Можно увеличить или уменьшить при компиляции. Так что, пересобирайте пакет из исходников (или попросите кого-нибудь).
« Последнее редактирование: 30.10.2016 02:09:36 от Dmytro »

Оффлайн berkut_174

  • Мастер
  • ***
  • Сообщений: 7 152
Dmytro
Спасибо! Но такой вариант меня не устроит, мне нужно универсальное решение, если бы я мог изменить значение в ходе выполнения скрипта... а так я уже сделал ещё более мелкими блоками, поплатившись скоростью отправки данных в базу.

В общем-то очень печально, что такое маленькое значение установлено по умолчанию, наверняка этому есть объяснение, возможно, какие-то утечки памяти происходят при большом лимите... или ещё чего.

Теме статус [решено].
Сноси Винду, переходи на Линукс ! :)

Оффлайн Dmytro

  • Мастер
  • ***
  • Сообщений: 1 001
В общем-то очень печально, что такое маленькое значение установлено по умолчанию, наверняка этому есть объяснение, возможно, какие-то утечки памяти происходят при большом лимите... или ещё чего.
Где-то вчера прочитал, что в первых версиях ограничений не было совсем. Поэтому, при высоких значениях программа могла вести себя непредсказуемо. Поэтому, поставили ограничения и в число стандартных тестов внесли проверку работы при максимальных значениях.

мне нужно универсальное решение
Только использовать СУБД, рассчитанные на бОльшую нагрузку.

Оффлайн berkut_174

  • Мастер
  • ***
  • Сообщений: 7 152
Про изначальную проблему, в данном случае ограничение накладывается ни на длину оператора SQL (SQLITE_MAX_SQL_LENGTH = 1000000), а на SQLITE_MAX_COMPOUND_SELECT, должно быть не более 500. :-)
Сноси Винду, переходи на Линукс ! :)

Оффлайн Dmytro

  • Мастер
  • ***
  • Сообщений: 1 001
Наверное, точнее будет сказать, что на оба эти параметра. Ведь превысить можно любой из них. И абсолютно все ограничения зашиваются жестко при компиляции. Увеличить можно все, кроме максимального размера файла базы, который составляет 32ТБ.