在单个表上使用多个连接优化sql查询

时间:2017-08-22 12:43:13

标签: sql postgresql join left-join

tbl_picklist表

id     value
1      John
2      Mumbai
3      San Diego
4      CA
5      Jerry

tbl_user表

id     picklist_id_name    email
1      1                   john@test.com
2      8                   jerry@gmail.com

tbl_profile表

id     user_id   picklist_id_addr    picklist_id_addr2   designation
1       1         3                   5                   Dev
3       2         7                   3                   QA   

领料单是您将获得地址,地址2和名称的值的表格, 我写的查询给了我想要的结果

SELECT
    u.email,
    p1.value AS username,
    p2.value AS addr1,
    p3.value AS addr2
FROM tbl_user u
LEFT JOIN tbl_picklist AS p1
    ON u.picklist_id_name = p1.id
LEFT JOIN tbl_profile pr
    ON pr.user_id = u.id
LEFT JOIN tbl_picklist AS p2
    ON p2.id = pr.picklist_id_addr
LEFT JOIN tbl_picklist AS p3
    ON p3.id = pr.picklist_id_addr2

结果:

email            username      addr1        addr2
john@test.com    John          Mumbai       San Diego
jerry@gmail.com  Jerry         CA           Mumbai

要获得上述结果,我需要在选项列表中编写3个连接, 有没有其他方式我只能通过选择列表表上的一个连接获得结果? 我在应用程序中有这种表结构,很多值都存储在picklist表中,它花了很多时间来执行这种查询。

2 个答案:

答案 0 :(得分:2)

当前的数据库结构不正确。 如果您有权限,则应重建它以优化查询并遵循规范化表单。 例如,picklist_id_addr,picklist_id_addr2及其值应该在一个表中,您可以在picklist_id_name或user_id上加入。

答案 1 :(得分:0)

我打算建议在你的表中添加一系列索引,以期加快查询速度,直到我意识到更大的问题是你当前的表设计。最大的罪犯是下表[{1}}:

tbl_picklist

您将在单个非标准化列中存储有关用户的所有类型的信息。相反,我建议只有两个表,一个用于用户信息,另一个用于地址信息。通过主外键关系将用户链接到地址。例如:

id     value
1      John
2      Mumbai
3      San Diego
4      CA
5      Jerry

tbl_user
id | email           | designation | address_id
1  | john@test.com   | dev         | 1
2  | jerry@gmail.com | QA          | 2

在这种简化的架构下,您只需要一个查询来构建整个用户记录:

tbl_address
id | city      | state     | country
1  | San Diego | CA        | USA
2  | Mumbai    | Bollywood | India

例如,如果您仍然需要优化上述查询或类似的查询,则只需要担心单个连接,而不需要担心SELECT t1.email, t1.designation, t2.city, t2.state, t2.country FROM tbl_user t1 INNER JOIN tbl_address t2 ON t1.address_id = t2.id 子句。在这个人为的例子中,WHERE上的索引应该可以解决问题。