我正在使用火鸟 2.1。我想优化以下查询,因为即使在一个小数据集(cca 500 条记录)上,它的执行速度也非常慢(几乎 2 秒):
表客户端存储个人和公司/公司组。(ClientType=0 人,ClientType=1 公司) 主键:ClientID
表 ClientContacts 存储哪些人与哪些公司相关联:ClientID 是公司的 ID,ContactClientID 是与公司相关联的人员的 ID。主键:ClientID、ContactClientID
TABLE CompanyGroups 存储哪些公司链接到哪些公司组:ParentClientID 是公司组的 ID,ClientID 是附加到公司组的公司 ID。主键:ParentClientID、ClientID
所以一个人可能属于多个公司,一个公司可能属于多个公司集团。
我想列出所有个人和公司。对于个人,我想显示它属于哪些公司,对于公司,我想显示该公司属于哪些公司集团。
最重要的是,我需要按个人/公司所属的公司/公司组的名称进行搜索。在 Firebird 中,由于聚合函数“LIST”,我可以使用派生表来实现这一点。
这是查询:
SELECT C.ClientID,
C.ClientType,
C.ClientName,
IIF(C.ClientType = 0, PCN.PCompanyNames, CCN.CCompanyNames),
FROM Clients C
LEFT JOIN (SELECT CC.ContactClientID, LIST(CL.ClientName, ', ') AS PCompanyNames
FROM ClientContacts CC LEFT JOIN Clients CL ON CL.ClientID = CC.ClientID WHERE
CL.AccessRights = 0 OR CL.UserID = :UserID OR (CL.AccessRights = 2 AND
CL.ClientID IN (SELECT ClientID FROM ClientRights WHERE UserID = :UserID))
GROUP BY CC.ContactClientID) PCN ON PCN.ContactClientID = C.ClientID AND C.ClientType = 0
LEFT JOIN (SELECT CG.ClientID, LIST(CL.ClientName, ', ') AS CCompanyNames
FROM CompanyGroups CG LEFT JOIN Clients CL ON CL.ClientID = CG.ParentClientID WHERE
CL.AccessRights = 0 OR CL.UserID = :UserID OR (CL.AccessRights = 2 AND
CL.ClientID IN (SELECT ClientID FROM ClientRights WHERE UserID = :UserID))
GROUP BY CG.ClientID) CCN ON CCN.ClientID = C.ClientID AND C.ClientType = 1
WHERE (C.AccessRights = 0
OR C.UserID = :UserID
OR (C.AccessRights = 2 AND C.ClientID IN (SELECT ClientID FROM ClientRights WHERE UserID = :UserID)))
AND (:SearchStr IS NULL
OR (PCN.PCompanyNames COLLATE UNICODE_CI LIKE '%' || :SearchStr || '%'
OR CCN.CCompanyNames COLLATE UNICODE_CI LIKE '%' || :SearchStr || '%'))
更新查询计划,首先是上面的查询,其次是上面的查询,到处都没有 WHERE 子句(没有 IN SELECT)
Field #01: CLIENTS.CLIENTID Alias:CLIENTID Type:INTEGER
Field #02: CLIENTS.CLIENTTYPE Alias:CLIENTTYPE Type:INTEGER
Field #03: CLIENTS.CLIENTNAME Alias:CLIENTNAME Type:STRING(1000)
Field #04: .CASE Alias:CASE Type:BLOB SUB_TYPE 1
PLAN (PCN CLIENTRIGHTS INDEX (RDB$PRIMARY46))
PLAN (CCN CLIENTRIGHTS INDEX (RDB$PRIMARY46))
PLAN (CLIENTRIGHTS INDEX (RDB$PRIMARY46))
PLAN JOIN (JOIN (C INDEX (IDX_CLIENTS_ACCESSRIGHTS, IDX_CLIENTS_USERID, IDX_CLIENTS_ACCESSRIGHTS), SORT (JOIN (PCN CC NATURAL, PCN CL INDEX (RDB$PRIMARY12)))), SORT (JOIN (CCN CG NATURAL, CCN CL INDEX (RDB$PRIMARY12))))
119643 fetches, 0 marks, 0 reads, 0 writes.
0 inserts, 0 updates, 0 deletes, 19977 index, 19629 seq.
Delta memory: 321686664 bytes.
Total execution time: 1.531s
Field #01: CLIENTS.CLIENTID Alias:CLIENTID Type:INTEGER
Field #02: CLIENTS.CLIENTTYPE Alias:CLIENTTYPE Type:INTEGER
Field #03: CLIENTS.CLIENTNAME Alias:CLIENTNAME Type:STRING(1000)
Field #04: .CASE Alias:CASE Type:BLOB SUB_TYPE 1
PLAN JOIN (JOIN (C NATURAL, SORT (JOIN (PCN CC NATURAL, PCN CL INDEX (RDB$PRIMARY12)))), SORT (JOIN (CCN CG NATURAL, CCN CL INDEX (RDB$PRIMARY12))))
119289 fetches, 0 marks, 0 reads, 0 writes.
0 inserts, 0 updates, 0 deletes, 19646 index, 19832 seq.
Delta memory: 321690896 bytes.
Total execution time: 1.406s