【发布时间】:2014-07-14 21:45:03
【问题描述】:
有 sql-query,在 POSTGRES 9.1 中运行。该查询使用 24 个 LEFT JOIN。 每个连接表可以有 1 到 10-15 个数据行,与前一个表相关。由于 sql-query 我有很多数据行,彼此相差 1 个值
SQL 查询示例:
SELECT
asw.surname,
asw.firstname,
asw.fathername,
asw.birthday,
asbe.institue_title,
asht.honour_type
/* Other fields are hidden to simplify example */
FROM
/* Table of staff */
agency_socworker AS asw
LEFT JOIN
/* Table contains staff honours */
agency_socworkerhonours AS ash
ON asw.id = ash.socworker_id
LEFT JOIN
/* Table contains name of the certain honour_id */
agency_socworker_honourtype AS asht
ON ash.honour_name_id = asht.id
LEFT JOIN
/* Table contains education data */
agency_socworker_base_edu AS asbe
ON asbe.socworker_id = asw.id
/* Other part of query is hidden to simplify example */
ORDER BY
asw.surname ASC
结果示例:
surname---firstname---fathername---birthday-----honour_type----institue_title1
Surname---firstname---fathername---1965-01-01---TYPE1----------institue_title1
Surname---firstname---fathername---1965-01-01---TYPE2----------institue_title1
Surname---firstname---fathername---1965-01-01---TYPE3----------institue_title1
Surname---firstname---fathername---1965-01-01---TYPE4----------institue_title1
Surname---firstname---fathername---1965-01-01---TYPE5----------institue_title1
Surname---firstname---fathername---1965-01-01---TYPE1----------institue_title2
Surname---firstname---fathername---1965-01-01---TYPE2----------institue_title2
Surname---firstname---fathername---1965-01-01---TYPE3----------institue_title2
Surname---firstname---fathername---1965-01-01---TYPE4----------institue_title2
Surname---firstname---fathername---1965-01-01---TYPE5----------institue_title2
我想得到以下内容:
surname---firstname---fathername---birthday--------honour_type----------------------institue_title
Surname---firstname---fathername---1965-01-01---TYPE1, TYPE2, TYPE3, TYPE4, TYPE5---institue_title1, institue_title2
我使用array_agg函数来实现这个目标:
SELECT
asw.surname,
asw.firstname,
asw.fathername,
asw.birthday,
array_agg( asbe.institue_title ) AS honour_type
array_agg( asht.honour_type ) AS honour_type
/* Other fields are hidden to simplify example */
FROM
/* Table of staff */
agency_socworker AS asw
LEFT JOIN
/* Table contains staff honours */ agency_socworkerhonours AS ash
ON asw.id = ash.socworker_id
LEFT JOIN
/* Table contains name of the certain honour_id */
agency_socworker_honourtype AS asht
ON ash.honour_name_id = asht.id
LEFT JOIN
/* Table contains education data */
agency_socworker_base_edu AS asbe
ON asbe.socworker_id = asw.id
GROUP BY
asw.surname,
asw.firstname,
asw.fathername,
asw.birthday
ORDER BY
asw.surname ASC
但这需要对不在“array_agg”函数中的字段进行“GROUP BY”语句。由于完整的 SQL 查询包含 24 个连接表,我必须使用
GROUP BY
asw.surname,
asw.firstname,
asw.fathername,
asw.birthday,
ag.shortname,
agr.shortname,
agr.fullname,
agdis.shortname,
agdis.fullname,
aorg.name,
agc.name,
agc.atype,
asnji.id,
asnji.new_job_contract_date,
assp.struct_name,
agdep.number,
agdep_type.name,
agdep_type.dtype,
aswl.work_length_checkdate,
aswl.work_length_protection_length_years,
aswl.work_length_protection_length_days,
aswl.work_length_protection_length_months
这会减慢查询速度。使用“分组依据”,获取前 100 个数据行需要 2 秒。如果没有“array_agg”和“group by”语句,它需要 250 毫秒,但我必须有分页。我无法进行分页,因为我不知道有多少数据行可以获得 100 个唯一行。
【问题讨论】:
标签: postgresql query-optimization postgresql-9.1