我正在尝试优化此处经常使用的Crystal Report。我成功地优化了大量查询,但我仍然有一个最后的瓶颈:这是从报告生成的主要查询。
SELECT
A.*,
B.*,
C.*,
D.*,
E."N",
F."N",
G."N"
FROM
A
LEFT OUTER JOIN B ON
A."PK" = B."FK"
LEFT OUTER JOIN C ON
A."PK" = C."FK"
LEFT OUTER JOIN D ON
A."FK" = D."PK"
LEFT OUTER JOIN E ON
A."PK" = E."FK"
LEFT OUTER JOIN F ON
A."PK" = F."FK"
LEFT OUTER JOIN G ON
A."PK" = G."FK"
WHERE A.PK = ####
A,B,C和D是表格。 E,F,G是简单的观点。
如您所见,该报告生成了多个LEFT JOINS。此查询需要2.28秒才能完成(来自计划查看器统计信息)。我确定了三个似乎有问题的联接。如果我从查询中删除E,F,G,它几乎是即时的(来自相同统计数据的0.0009s)
SELECT
A.*,
B.*,
C.*,
D.*
FROM
A
LEFT OUTER JOIN B ON
A."PK" = B."FK"
LEFT OUTER JOIN C ON
A."PK" = C."FK"
LEFT OUTER JOIN D ON
A."FK" = D."PK"
WHERE A.PK = ####
我认为这可能是缓慢的观点,但如果我这样做......
SELECT *
FROM E
WHERE E.FK = ####
......它几乎是即时的(0.0009s)
所有表都有PKs-FK索引。 视图E,F,G都以[FK | N]为列返回一行或没有行,因此结果列为NULL或数字。
你知道如何快速进行这个查询吗?
PS:如果我用INNER JOINS替换LEFT OUTER JOINS,主查询会变得很快......: - /
或者尝试将此查询拆分为报表上的多个查询会是更好的解决方案吗?
谢谢!
答案 0 :(得分:0)
问题可能是因为您创建了一个包含5个表的巨大笛卡尔积,所有表都以某种方式加入A
A
和D
只会为产品贡献一条记录) 。拥有如此大的笛卡尔积将在Sybase内部消耗相当多的内存。您的查询很可能是错误的。
答案 1 :(得分:0)
我会创建用于查找E,F和G的函数,而不是加入它们。 这样,优化者就很难混淆并试图做出愚蠢的事情。
SELECT
A.*,
B.*,
C.*,
D.*,
GET_E(A."PK"),
GET_F(A."PK"),
GET_G(A."PK")
FROM
A
LEFT OUTER JOIN B ON
A."PK" = B."FK"
LEFT OUTER JOIN C ON
A."PK" = C."FK"
LEFT OUTER JOIN D ON
A."FK" = D."PK"
WHERE A.PK = ####