Postgresql 连接多个表

标签 postgresql

好的,在过去 6 年转向 MongoDB 之前,我使用 MySQL/postgres 多年,现在我正在画一些空白。我一直在寻找执行此操作的最佳方法,使用我非常简单的数据集,查询时间平均为 20 毫秒。 < 100 行似乎很疯狂。我可能以 super 复杂的方式做到了这一点 :)

因此这里的想法是获取用户有权访问的类(class)列表,以及他们的最新测验分数和最新类(class)进度(他们在类(class)中完成了多少)。

SELECT DISTINCT ON (m.id) m.id,m.lesson_name,m.course_name,m.order,m.progress,m.thumb,m.media_id,m.length,m.quiz_id,m.score FROM (SELECT
    lessons.id,lessons.name AS lesson_name,courses.name AS course_name, lesson_courses."order", less_prog.progress, lessons.thumb, lessons.media_id, lessons.length, lesson_quiz.id as quiz_id, acclessq.score,acclessq.timestamp as atime, less_prog.timestamp as ltime
    FROM lessons
    INNER JOIN lesson_courses ON lessons."id" = lesson_courses.lessons_id
    INNER JOIN plan_courses ON plan_courses.courses_id = lesson_courses.courses_id
    INNER JOIN courses ON courses.id = lesson_courses.courses_id
    LEFT JOIN (
        SELECT progress,lessons_id,timestamp FROM lesson_progress WHERE accounts_id = 1
    ) as less_prog ON less_prog.lessons_id = lessons.id
    LEFT JOIN (
        SELECT lesson_quiz.id,lesson_quiz.lessons_id FROM lesson_quiz
    ) as lesson_quiz ON lessons.id=lesson_quiz.lessons_id
    LEFT JOIN (
        SELECT score,lesson_quiz_id,account_lesson_quiz.timestamp FROM account_lesson_quiz WHERE account_lesson_quiz.accounts_id = 1
    ) as acclessq ON lesson_quiz.id=acclessq.lesson_quiz_id
    LEFT JOIN (
        SELECT accounts_id,plans_id FROM account_plans WHERE accounts_id = 1
    ) as account_plans ON account_plans.plans_id = plan_courses.plans_id
    GROUP BY lessons.id,courses.id,courses.name,lesson_courses.order,less_prog.progress, lessons.thumb, lessons.media_id, lessons.length, quiz_id, acclessq.score,atime,ltime
    ORDER BY courses.id, lesson_courses."order",atime DESC,ltime DESC) m

我确定我做得太疯狂了,但我得到了正确的结果...那么当我们有更多结果时,我如何简化它并降低性能?

更新:尝试使用 WITH 重写。性能下降到平均 15 毫秒。它看起来确实干净多了,但我仍然觉得对于这么少的数据来说它太高了。

WITH lesson_quiz AS (SELECT lesson_quiz.id,lesson_quiz.lessons_id FROM 
lesson_quiz),
less_prog AS (SELECT progress,lessons_id,timestamp FROM lesson_progress 
WHERE accounts_id = 1),
acclessq AS (SELECT score,lesson_quiz_id,account_lesson_quiz.timestamp 
FROM account_lesson_quiz WHERE account_lesson_quiz.accounts_id = 1),
acc_plans AS (SELECT accounts_id,plans_id FROM account_plans WHERE 
accounts_id = 1)

SELECT DISTINCT ON (lessons.id)
lessons.id,lessons.name AS lesson_name,courses.name AS course_name, lesson_courses."order", less_prog.progress, lessons.thumb, lessons.media_id, lessons.length, lesson_quiz.id as quiz_id, acclessq.score
FROM lessons
INNER JOIN lesson_courses ON lessons."id" = lesson_courses.lessons_id
INNER JOIN plan_courses ON plan_courses.courses_id = lesson_courses.courses_id
INNER JOIN courses ON courses.id = lesson_courses.courses_id
LEFT JOIN less_prog ON less_prog.lessons_id = lessons.id
LEFT JOIN lesson_quiz ON lessons.id=lesson_quiz.lessons_id
LEFT JOIN acclessq ON lesson_quiz.id=acclessq.lesson_quiz_id
LEFT JOIN acc_plans ON acc_plans.plans_id = plan_courses.plans_id
ORDER BY id, acclessq.timestamp DESC, less_prog.timestamp DESC

这是查询计划:https://explain.depesz.com/s/IvPl

最佳答案

GROUP BY 和 DISTINCT 通常实现相同的目标。您确定需要 DISTINCT 吗?如果需要,删除它后它的性能会更好吗?

感谢您提供查询计划。也许时间戳 DESC 列上的索引会有所帮助?似乎大部分时间都花在了排序上。

关于Postgresql 连接多个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47253887/

相关文章:

postgresql - 使用异常处理修复 PL/pgsql (PostgreSQL) 中的外键约束

用于优化搜索性能的 PostgreSQL jsonb 索引

django - 在 Django 管理界面中链接以直接从数据库下载模型字段

postgresql - 无法将 ".sql"文件恢复到 pgadmin4

django - 将 manage.py 指向特定的 PostgreSQL 模式

windows - 在win7中删除旧的PostgreSQL数据目录

Python/PostgreSQL - 检查服务器是否正在运行

database - 在多个 postgresql 集群中创建角色

postgresql - 数字类型 : "(0.0000000000000000,8)" 的输入语法无效

ruby-on-rails - rails HABTM : Select everything a that a record 'has'