Запросы SQLite работают медленно, нужна помощь по оптимизации - PullRequest
2 голосов
/ 26 мая 2011

У меня есть БД SQLite с примерно 24 тыс. Записей в одной из таблиц, 15 в другой.Таблица с 15 записями содержит информацию о формах, которые должны быть заполнены пользователями (примерно 1 тыс. Пользователей).Таблица с 24k записями содержит информацию о том, какие формы были заполнены кем и когда.Когда пользователь входит в систему, время ожидания запросов составляет ~ 3/4 секунды, чтобы определить, что пользователь завершил на данный момент.Слишком долго для моего клиента.Я знаю, что не могу выполнять свои запросы наилучшим образом, потому что они содержатся в цикле.Но я не могу понять, как оптимизировать мой запрос.

Запросы выполняются следующим образом:

1) Выберите все формы и информацию

$result = $db->query("SELECT * FROM tbl_forms");
while($row = $result->fetchArray()){
//Run other query 2 here
}

2) Для каждой формы / строки запустите запрос, который выяснит, какие самые последние сведения о заполнении этой формы для пользователя.

$complete = $db->querySingle("SELECT * FROM tbl_completion AS forms1 
      WHERE userid='{$_SESSION['userid']}' AND form_id='{$row['id']}' AND forms1.id IN 
      (SELECT MAX(id) FROM tbl_completion 
      GROUP BY tbl_completion.userid, tbl_completion.form_id)", true);          

Существует 15 форм, поэтому в общей сложности выполняется 16 запросов.,Однако, с моей структурой таблицы, я не уверен, как получить «самую последнюю» (aka max id формы) информацию формы, используя вместо этого 1 объединенный запрос.

Моя структура таблицы выглядит так:

tbl_forms:
id | form_name | deadline | required | type | quicklink

tbl_completion:
id | userid | form_id | form_completion | form_path | timestamp | accept | reject

Редактировать: Index on tbl_forms (id), Index on tbl_forms (id, form_name), Index on tbl_complete (id)

Я пытался использовать запрос, подобный следующему:

SELECT * FROM tbl_completion AS forms1 
LEFT OUTER JOIN tbl_forms ON forms1.form_id = tbl_forms.id 
WHERE forms1.userid='testuser' AND forms1.id IN 
(SELECT MAX(id) FROM tbl_completion GROUP BY tbl_completion.userid, tbl_completion.form_id)

, который даст мне самую последнюю информацию озаполненные формы, а также информация о формах, но единственная проблема в этом заключается в том, что мне нужно вывести все формы в таблицу (например: форма 1-неполная, форма 2-заполненная и т. д.), я не могу понять, какчтобы заставить его работать с левой таблицей tbl_forms и получать всю информацию о форме, а также информацию о самой последней форме tbl_completion.Я также попытался сделать 3 LOJ с последним «столом» в качестве временного стола с максимальным значением, но это было очень медленно И не давало мне того, что я хотел.

Кто-нибудь может помочь ??Есть ли лучше оптимизированный запрос, который я могу выполнить один раз, или я могу сделать что-то еще на стороне БД, чтобы ускорить это?Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 26 мая 2011

Вам не хватает индексов.См .:

DO и DONT для индексов

Кроме того, SELECT MAX(id) FROM tbl_completion GROUP BY tbl_completion.userid, tbl_completion.form_id может предположительно отбрасывать ненужные строки, если вы добавите свой идентификатор пользователя в предложении where.

1 голос
/ 26 мая 2011

Похоже, вы сталкиваетесь с ограничениями параллелизма SQLite.SQLite не поддерживает одновременную запись, поэтому, если у вас много пользователей, вы в конечном итоге получите много конфликтов.Вам следует подумать о переходе на другую СУБД, чтобы удовлетворить ваши потребности в масштабировании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...