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, но это было очень медленно и не дало мне то, что я хотел.
Может ли кто-нибудь помочь?? Есть ли более оптимизированный запрос, который я могу выполнить один раз, или я могу сделать что-то еще на стороне БД, чтобы ускорить это? Заранее спасибо.
2 ответов:
Вы пропускаете индексы. Смотрите:
Кроме того,
SELECT MAX(id) FROM tbl_completion GROUP BY tbl_completion.userid, tbl_completion.form_idпредположительно может отбросить ненужные строки, Если вы добавите свой идентификатор пользователя в предложение where.
Похоже, что вы столкнулись с ограничениями параллелизма SQLite. SQLite не поддерживает одновременную запись, поэтому, если у вас много пользователей, вы в конечном итоге будете иметь много разногласий. Вы должны рассмотреть возможность перехода на другую СУБД, чтобы удовлетворить ваши потребности в масштабировании.
Comments