SQLite запросы работают медленно, нужна помощь оптимизации



У меня есть база данных SQLite с примерно 24k записями в одной из таблиц, 15 в другой. Таблица с 15 записями содержит информацию о формах, которые должны быть заполнены пользователями (примерно 1k пользователей). Таблица с записями 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 form 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 с последним "столом" в качестве временного стола, удерживающего maxid, но это было очень медленно и не дало мне то, что я хотел.



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

2 ответов:

Вы пропускаете индексы. Смотрите:

DOs и Dont для индексов

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

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

Comments

    Ничего не найдено.