Android: SQLite FTS3 замедляется при извлечении следующих / предыдущих строк - PullRequest
1 голос
/ 20 июня 2011

У меня есть база данных sqlite, в которой на данный момент есть несколько таблиц, в самой большой из которых более 10000 строк.Эта таблица имеет четыре столбца: идентификатор, термин, определение, категория.Я использовал модуль FTS3 для ускорения поиска, который очень помог.Однако теперь, когда я пытаюсь получить «следующую» или «предыдущую» строку из таблицы, это занимает больше времени, чем было до того, как я начал использовать FTS3.

Вот как я создаю виртуальную таблицу:

CREATE VIRTUAL TABLE profanity USING fts3(_id integer primary key,name text,definition text,category text);

Вот как я выбираю следующие / предыдущие строки:

SELECT * FROM dictionary WHERE _id < "+id + " ORDER BY _id DESC LIMIT 1
SELECT * FROM dictionary WHERE _id > "+id + " ORDER BY _id LIMIT 1

Когда я запускаю эти операторы в виртуальнойтаблица:

  • СЛЕДУЮЩИЙ термин выбирается в течение ~ 300 мс ,
  • ПРЕДЫДУЩИЙ термин выбирается в течение ~ 200 мс

Когда я делаю это с обычной таблицей (созданной без FTS3):

  • СЛЕДУЮЩИЙ термин выбирается в течение ~ 3 мс ,
  • ПРЕДЫДУЩИЙ терминизвлекать в течение ~ 2 мс

Почему такая большая разница?Можно ли как-нибудь улучшить эту скорость?

РЕДАКТИРОВАНИЕ: Я до сих пор не могу заставить его работать!

Ответы [ 2 ]

0 голосов
/ 24 июня 2011

Созданная вами виртуальная таблица предназначена для предоставления полнотекстовых запросов. Он не нацелен на быструю обработку стандартных запросов с использованием PK в состоянии условия. В этом случае в вашем столбце _id нет индекса, поэтому SQLite, вероятно, выполняет полное сканирование таблицы. Следующая проблема - ваш запрос - он абсолютно неэффективен. Попробуйте что-то вроде этого (не проверено):

SELECT * FROM dictionary WHERE _id = (select max(_id) from dictionary where _id < ?)

Следующее, что вы можете рассмотреть, - это редизайн вашего приложения. Вместо загрузки 1 строки вам, может быть, вы должны получить, скажем, 40, загрузить их в память и выполнить фоновую загрузку данных, когда до одного из концов меньше n. Длинная операция SQL станет невидимой для пользователя, даже если она будет длиться 3 с вместо 0,3 с

0 голосов
/ 20 июня 2011

Если вы запускаете LIMIT 1 для начала, вы можете полностью удалить заказ по предложению. Это может помочь. Однако я не знаком с FTS3.

Вы также можете просто присвоить свою переменную id a ++ или - и утверждать `WHERE _id =" + id + "LIMIT 1", что сделало бы один поиск вместо <или>.

Редактировать: и теперь, когда я оглядываюсь назад на то, что набрал, если вы делаете это таким образом, вы можете просто полностью удалить LIMIT 1, поскольку ваш _id - это ваш pk и должен быть уникальным.

эй, смотри, необработанный пункт!

...