简体   繁体   English

如何使此查询运行更快

[英]How can I make this query run faster

I am running this query on my website in order to find a ToDo list based on specific criteria. 我正在我的网站上运行此查询,以便根据特定条件查找待办事项列表。 But it runs too slow and it is probably possible to write it in another way. 但是它运行太慢,可能可以用其他方式编写它。

SELECT * FROM lesson WHERE 
id IN 
(SELECT `lesson_id` FROM `localization_logging` 
WHERE `language_id` = 2 AND `action_id` = 1) 
AND `id` NOT IN 
(SELECT `lesson_id` FROM `localization_logging` 
WHERE `language_id` = 2 AND `part_id` = 1 AND `action_id` = 6)

What the query does is that it looks in the lesson table to find all lesson list names and then checks if a specific task is done. 该查询所做的是,它在课程表中查找所有课程列表名称,然后检查特定任务是否完成。 If the task is done in one todo than show it in the next. 如果任务是在一个任务中完成的,则在下一个任务中显示。 Action 1 is done but not action 6 in this case. 在这种情况下,将执行操作1,但不执行操作6。

I hope I'm explaining this good enough. 我希望我能解释得足够好。 On my local machine the query takes 1.8 seconds, and sometimes I have to print multiple lists next to each others and then it takes 1.8 times the lists which makes the page load super slow. 在我的本地计算机上,查询需要1.8秒,有时我必须将多个列表彼此相邻打印,然后它需要使用1.8倍的列表,这使得页面加载非常慢。

Something like this for mark id as completed: 这样的标记ID已完成:

SELECT l.*, SUM(ll.action_id=6) completed FROM lesson l
INNER JOIN localization_logging ll ON ll.lesson_id = l.id
WHERE ll.language_id = 2 AND 
(
 ll.action_id = 1
  OR 
 ll.action_id = 6 AND ll.part_id == 1
)
GROUP BY l.id

And now we can wrap it with: 现在,我们可以将其包装为:

SELECT t.* FROM (...) t WHERE t.completed = 0

You'll usually get faster queries filtering rows with INNER/LEFT JOIN , but you need to test it. 通常,您可以使用INNER/LEFT JOIN获得更快的查询来过滤行,但是您需要对其进行测试。

SELECT lesson.* FROM lesson
INNER JOIN localization_logging task1
    ON lesson.id = task1.lesson_id
LEFT JOIN localization_logging task2
    ON lesson.id = task2.lesson_id
    AND task2.language_id = 2
    AND task2.part_id = 1
    AND task2.action_id = 6
WHERE task1.language_id = 2
AND task1.action_id = 1
AND task2.lesson_id IS NULL

Second table is joined on multiple conditions, but have to list them within ON clause because only results that were in result "force joined" as nulls (left join means left side stays no matter what) are required. 第二个表在多个条件下被联接,但是必须在ON子句中列出它们,因为仅需要将结果“强制联接”为空的结果(空联接意味着无论什么情况都保留)。

Btw. 顺便说一句。 You'll get multiple rows from lesson if task1 condition is not limiting results to one row - GROUP BY lesson.id then. 如果task1条件不将结果限制为一行,则您将从lesson获得多行-然后是GROUP BY lesson.id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM