[SQLite] Медленное выполнение запроса
От: algol Россия about:blank
Дата: 20.12.10 14:17
Оценка:
Подскажите, почему может медленно выполняться запрос вида "UPDATE table1 SET field1 = %d WHERE rowid = %d"
Для таблицы в 1000 записей это занимает около 200 мс и на порядки больше чем время остальных запросов. Куда смотреть, что проверить?
sqlite rowid
Re: [SQLite] Медленное выполнение запроса
От: MasterZiv СССР  
Дата: 20.12.10 14:32
Оценка:
On 20.12.2010 17:17, algol wrote:

> Для таблицы в 1000 записей это занимает около 200 мс и на порядки больше чем


Вообще-то 200 милисекунд -- вполне хорошее время выполнения запроса.

Секунды -- уже много (для такого запроса), а вот так -- очень даже хорошо.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: [SQLite] Медленное выполнение запроса
От: algol Россия about:blank
Дата: 20.12.10 14:46
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Вообще-то 200 милисекунд -- вполне хорошее время выполнения запроса.

MZ>Секунды -- уже много (для такого запроса), а вот так -- очень даже хорошо.

Нет, для такой маленькой таблицы это много даже в случае перебора всех записей. rowid как я понимаю, это типа primary key, и должно происходить обращение по индексу. Если я меняю запрос на аналогичный "UPDATE table1 SET field1 = %d WHERE field2 = %s", то время выполнения 2 мс (есть индекс по field2). Это что, глюк SQLite или я что-то не понимаю?
Re: [SQLite] Медленное выполнение запроса
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 20.12.10 15:01
Оценка:
Здравствуйте, algol, Вы писали:

A>Подскажите, почему может медленно выполняться запрос вида "UPDATE table1 SET field1 = %d WHERE rowid = %d"

A>Для таблицы в 1000 записей это занимает около 200 мс и на порядки больше чем время остальных запросов. Куда смотреть, что проверить?

Индексы там есть? время может на перестройку индекса уходить
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[2]: [SQLite] Медленное выполнение запроса
От: algol Россия about:blank
Дата: 20.12.10 15:10
Оценка:
Здравствуйте, Sshur, Вы писали:

A>>Подскажите, почему может медленно выполняться запрос вида "UPDATE table1 SET field1 = %d WHERE rowid = %d"

S>Индексы там есть? время может на перестройку индекса уходить

Индекса по field1 нет.
Re: [SQLite] Медленное выполнение запроса
От: Anton Batenev Россия https://github.com/abbat
Дата: 20.12.10 18:00
Оценка:
Здравствуйте, algol, Вы писали:

a> Подскажите, почему может медленно выполняться запрос вида "UPDATE table1 SET field1 = %d WHERE rowid = %d"

a> Для таблицы в 1000 записей это занимает около 200 мс и на порядки больше чем время остальных запросов. Куда смотреть, что проверить?

А DDL таблички и конкретные тестовые значения можно посмотреть?
avalon 1.0rc3 rev 376, zlib 1.2.3
Re[3]: [SQLite] Медленное выполнение запроса
От: MasterZiv СССР  
Дата: 21.12.10 07:34
Оценка:
On 20.12.2010 17:46, algol wrote:

> Нет, для такой маленькой таблицы это много даже в случае перебора всех записей.

> rowid как я понимаю, это типа primary key, и должно происходить обращение по

Это примерно время записи на диск+накладуха от самой СУБД. Если ты не согласен,
обоснуй, почему тебе кажется, что это много. Не на пальцах, а в цифрах.
Posted via RSDN NNTP Server 2.1 beta
Re: [SQLite] Медленное выполнение запроса
От: MasterZiv СССР  
Дата: 21.12.10 07:36
Оценка:
On 20.12.2010 17:17, algol wrote:
> это занимает около 200 мс и на порядки больше чем время остальных запросов.

Каковы остальные-то запросы ?
Posted via RSDN NNTP Server 2.1 beta
Re: [SQLite] Медленное выполнение запроса
От: Gaperton http://gaperton.livejournal.com
Дата: 21.12.10 09:20
Оценка:
Здравствуйте, algol, Вы писали:

A>Подскажите, почему может медленно выполняться запрос вида "UPDATE table1 SET field1 = %d WHERE rowid = %d"

A>Для таблицы в 1000 записей это занимает около 200 мс и на порядки больше чем время остальных запросов. Куда смотреть, что проверить?

PRIMARY KEY для чего-нибудь указывал?
Re[2]: [SQLite] Медленное выполнение запроса
От: algol Россия about:blank
Дата: 21.12.10 09:48
Оценка:
Здравствуйте, Anton Batenev, Вы писали:

AB>А DDL таблички и конкретные тестовые значения можно посмотреть?


Все очень просто:
CREATE TABLE files (path text, ext text, curver int)
CREATE INDEX IF NOT EXISTS path_idx ON files(path)
CREATE INDEX IF NOT EXISTS ext_idx ON files(ext)

path и ext — путь к файлу и расширение соответственно, path уникален. curver — это rowid другой таблицы.

Медленно исполняемый запрос:
UPDATE files SET curver = %d WHERE rowid = %d
Идентичный запрос выполняется почти в 100 раз быстрее:
UPDATE files SET curver = %d WHERE path = '%s'
Еще одна деталь — обновляемая запись обычно добавляется непосредственно перед обновлением.
Re[4]: [SQLite] Медленное выполнение запроса
От: Pzz Россия https://github.com/alexpevzner
Дата: 21.12.10 18:48
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Это примерно время записи на диск+накладуха от самой СУБД. Если ты не согласен,

MZ>обоснуй, почему тебе кажется, что это много. Не на пальцах, а в цифрах.

200ms — многовато для времени записи на диск, если учесть, что seek time у современных дисков где-то 5-10ms
Re[5]: [SQLite] Медленное выполнение запроса
От: MasterZiv СССР  
Дата: 22.12.10 06:59
Оценка:
On 21.12.2010 21:48, Pzz wrote:

> 200ms — многовато для времени записи на диск, если учесть, что seek time у

> современных дисков где-то 5-10ms

Ещё СУБД должна сработать. От неё накладуху тоже надо учитывать.
Она тоже немаленькая.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: [SQLite] Медленное выполнение запроса
От: Gaperton http://gaperton.livejournal.com
Дата: 22.12.10 08:40
Оценка:
Здравствуйте, algol, Вы писали:

A>Все очень просто:

A>
A>CREATE TABLE files (path text, ext text, curver int)
A>CREATE INDEX IF NOT EXISTS path_idx ON files(path)
A>CREATE INDEX IF NOT EXISTS ext_idx ON files(ext)
A>

A>path и ext — путь к файлу и расширение соответственно, path уникален. curver — это rowid другой таблицы.

A>Медленно исполняемый запрос:

A>UPDATE files SET curver = %d WHERE rowid = %d
A>Идентичный запрос выполняется почти в 100 раз быстрее:
A>UPDATE files SET curver = %d WHERE path = '%s'
A>Еще одна деталь — обновляемая запись обычно добавляется непосредственно перед обновлением.

Это очень похоже на баг. Ибо в документации явно написано, что выборка по rowid должна быть вдвое быстрее, чем по руками созданному индексу PRIMARY KEY. Здесь же все наоборот. Этот вопрос лучше задать на форуме поддержки sqlite.
Re[3]: [SQLite] Медленное выполнение запроса
От: Anton Batenev Россия https://github.com/abbat
Дата: 22.12.10 16:27
Оценка: 9 (1) +1
Здравствуйте, algol, Вы писали:

a> Медленно исполняемый запрос:

a> UPDATE files SET curver = %d WHERE rowid = %d
a> Идентичный запрос выполняется почти в 100 раз быстрее:
a> UPDATE files SET curver = %d WHERE path = '%s'
a> Еще одна деталь — обновляемая запись обычно добавляется непосредственно перед обновлением.

Есть совершенно глупое предположение — а в случае второго запроса path стоит существующий в таблице или нет? Потому как я набросал быстрый тест — если path существует, то время запроса в два раза больше, чем с rowid и сопоставимо с 200ms (у меня 100ms), а вот если нет, то вставки не производится и оно реально отрабатывает в 100 раз быстрее.

P.S. 100ms для SQLite нормальное время, т.к. журнал транзакций, блокировки и все дела.
avalon 1.0rc3 rev 380, zlib 1.2.3
Re[4]: [SQLite] Медленное выполнение запроса
От: Gaperton http://gaperton.livejournal.com
Дата: 22.12.10 19:57
Оценка:
Здравствуйте, Anton Batenev, Вы писали:

AB>P.S. 100ms для SQLite нормальное время, т.к. журнал транзакций, блокировки и все дела.


Это не нормальное время, принимая во внимание данные, приведенные автором по скорости аналогичного update, с выборкой не по кластерному индексу (который в случае SQLite есть rowid), а по обычному. Не может быть так. Ибо разница, очевидно, только в поиске.
Re[4]: [SQLite] Медленное выполнение запроса
От: algol Россия about:blank
Дата: 22.12.10 20:16
Оценка:
Здравствуйте, Anton Batenev, Вы писали:

AB>Есть совершенно глупое предположение — а в случае второго запроса path стоит существующий в таблице или нет? Потому как я набросал быстрый тест — если path существует, то время запроса в два раза больше, чем с rowid и сопоставимо с 200ms (у меня 100ms), а вот если нет, то вставки не производится и оно реально отрабатывает в 100 раз быстрее.


По идее, оба запроса должны быть совершенно идентичны и обновлять ровно одну запись. rowid в первом запросе указывает на запись с path, указанным во втором запросе. Но это надо проверить, возможно там баг, тогда это все объясняет.

AB>P.S. 100ms для SQLite нормальное время, т.к. журнал транзакций, блокировки и все дела.


Операции выполняются в цикле, все закешировано. А 100мс — это 10 апдейтов в секунду. Это слишком медленно для миниатюрной таблицы и не стыкуется с данными по призводительности SQLite (http://www.sqlite.org/speed.html). Например 25000 updates в транзакции занимают 3,5 сек (0,14 мс на запись), 1000 INSERT без транзакции — 13 сек (13 мс на запись).
Ну, и по моим замерам INSERT в ту же таблицу отрабатывает за 5-10мс.
Re[5]: [SQLite] Медленное выполнение запроса
От: Anton Batenev Россия https://github.com/abbat
Дата: 23.12.10 13:03
Оценка:
Здравствуйте, Gaperton, Вы писали:

G> AB>P.S. 100ms для SQLite нормальное время, т.к. журнал транзакций, блокировки и все дела.

G> Это не нормальное время, принимая во внимание данные, приведенные автором по скорости аналогичного update, с выборкой не по кластерному индексу (который в случае SQLite есть rowid), а по обычному. Не может быть так. Ибо разница, очевидно, только в поиске.

В сообщении рядом я написал, что 100ms — это время, скажем так, одной атомарной операции изменения данных. И так же отдельно отметил, что в случае, если данные не меняются (т.е. под условие WHERE не попадает ни одной записи при обновлении), то скорость резко повышается, т.к. базе не требуется синхронизировать данные с файловой системой ибо они не менялись. А вот что у автора в WHERE вопрос пока открытый.

Что же касается тезиса о том, что выборка по кластерному индексу будет быстрее нежели по обычному, то я с ним полностью согласен — где-то в два раза, но на фоне операции синхронизации с ФС это может быть заметно только на больших объемах (ну или на скорости SELECT-ов).
avalon 1.0rc3 rev 380, zlib 1.2.3
Re[5]: [SQLite] Медленное выполнение запроса
От: Anton Batenev Россия https://github.com/abbat
Дата: 23.12.10 13:03
Оценка:
Здравствуйте, algol, Вы писали:

a> По идее, оба запроса должны быть совершенно идентичны и обновлять ровно одну запись. rowid в первом запросе указывает на запись с path, указанным во втором запросе. Но это надо проверить, возможно там баг, тогда это все объясняет.


Ждемс.

a> Операции выполняются в цикле, все закешировано. А 100мс — это 10 апдейтов в секунду. Это слишком медленно для миниатюрной таблицы и не стыкуется с данными по призводительности SQLite (http://www.sqlite.org/speed.html). Например 25000 updates в транзакции занимают 3,5 сек (0,14 мс на запись), 1000 INSERT без транзакции — 13 сек (13 мс на запись).


Я попробовал написать простой тест (по аналогии тестов по ссылке):

* вставка 100 записей без оборачивания в транзакцию (каждая запись суть транзакция): ~7000 ms (70 ms / запись)
* вставка 100 записей в одну транзакцию: ~150 ms (1.5 ms / запись)

* обновление одной записи в таблице 100 раз (каждое обновление суть транзакция): ~7500 ms (75 ms / запись)
* обновление 100 записей в таблице в одной транзакции: ~100 ms (1 ms / запись)

Т.е. соотношения между транзакция/не транзакция приблизительно сохраняются. Но тут надо учесть, что там тесты для SQLite 2.x, а у меня 3.x, а так же немного другое оборудование (в частности, далеко не шустрый винт). Если же провести тесты на обычном сервере с FreeBSD и нешифрованным UFS2, то там вставка 1000 записей без транзакции укладывается в те же 13 сек, а вот обновление в транзакции уже ~0.02ms / запись.

Т.о. следует известное правило при работе с SQLite — делать запросы на вставку / обновление пачками, которые обернуты в транзакции. Дополнительно можно сделать небольшие читы типа:

PRAGMA page_size = 32768;


P.S. И заметь — даже работая в транзакции все равно нахожусь где-то в минимальном пределе 100 ms — скорее всего это минимальное время для всяких блокировок, fsync-ов и прочего.
avalon 1.0rc3 rev 380, zlib 1.2.3
Re: [SQLite] Медленное выполнение запроса
От: 0xDEADBEEF Ниоткуда  
Дата: 23.12.10 13:58
Оценка:
Здравствуйте, algol, Вы писали:

A>Для таблицы в 1000 записей это занимает около 200 мс и на порядки больше чем время остальных запросов. Куда смотреть, что проверить?

Транзакция открыта? ...А то у SQLite есть такой эффект, что при авто-коммите оно тормозит...
__________
16.There is no cause so right that one cannot find a fool following it.
Re[6]: [SQLite] Медленное выполнение запроса
От: algol Россия about:blank
Дата: 24.12.10 09:44
Оценка:
Здравствуйте, Anton Batenev, Вы писали:

a>> По идее, оба запроса должны быть совершенно идентичны и обновлять ровно одну запись. rowid в первом запросе указывает на запись с path, указанным во втором запросе. Но это надо проверить, возможно там баг, тогда это все объясняет.

AB>Ждемс.

Да, ваше предположение подтвердилось. Дествительно при втором запросе фактически обновления не было. Это объясняет разницу во времени.
Но 200 мс на UPDATE — это слишком много, время нужно как-то уменьшать в разы.

AB>P.S. И заметь — даже работая в транзакции все равно нахожусь где-то в минимальном пределе 100 ms — скорее всего это минимальное время для всяких блокировок, fsync-ов и прочего.


Что-то не сходится. У меня INSERT в 2 таблицы в одной транзакции занимает 15-20 мс. На этом фоне 200 мс на обновление одного поля как-то не смотрится.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.