0

我在优化一些非常慢的查询时遇到了一些麻烦(技术和概念上的)。

这是我的原始查询:

select Con_Progr,
    Pre_Progr
from contribuente,
    preavviso_ru,
    comune,
    via
where [lots of where clauses]
    and ((Via_Progr = Con_Via_Sec) or (Via_Progr = Con_Via_Res and (Con_Via_Sec is null or Con_Via_Sec = '0')))
order by Con_Cognome,
    Con_Nome asc;

这个查询大约需要 38 秒来执行,这是一个非常慢的时间。我对其进行了一些操作,并设法加快了大约 0.1 秒,现在查询看起来像这样:

(select Con_Progr,
    Pre_Progr
from preavviso_ru
    join contribuente
        on Pre_Contribuente = Con_Progr
    join via
        on Via_Progr = Con_Via_Sec
    join comune
        on Via_Comune = Com_CC
where [lots of where clauses]
order by Con_Cognome,
    Con_Nome asc
)
union
(
select Con_Progr,
    Pre_Progr
from preavviso_ru
    join contribuente
        on Pre_Contribuente = Con_Progr
    join via
        on Via_Progr = Con_Via_Res
    join comune
        on Via_Comune = Com_CC
where [lots of where clauses]
    and (Con_Via_Sec is null or Con_Via_Sec = '0')
order by Con_Cognome,
    Con_Nome asc
)

如您所见,我在原始查询中拆分了 where 子句,该子句在OR两个不同的子查询中使用了运算符,然后将它们合并。这解决了速度问题。结果虽然并不完美,因为我失去了订购。我尝试选择子查询中的列,然后对该结果执行排序,如下所示:

select Con_Progr,
        Pre_Progr
from (
    [FIRST SUBQUERY]
) as T1 union (
    [SECOND SUBQUERY]
) as T2
order by Con_Cognome,
        Con_Nome asc

但我在“”附近收到语法错误union。有什么建议吗?

这是技术问题。现在对于概念,我认为这两个子查询非常相似(它们仅在连接子句和 where 子句上有所不同),有没有办法以更优雅的方式重新排列第二个查询(快速查询)?

4

1 回答 1

0

我解决了技术问题,我放错了括号:

select Con_Progr,
    Pre_Progr
from (
    [FIRST SUBQUERY]
union
    [SECOND SUBQUERY]
) as T
order by Con_Cognome,
    Con_Nome asc

现在它几乎可以完美地工作了(排序中仍然存在一些差异,但这不是问题。

关于查询的效率,我发现问题出OR在两个不同列上的条件,因为 MySQL 4.0(我使用它来解决向后兼容性问题)只允许一个表索引。但是,为什么它不至少使用这些索引之一。我再测试一下...

于 2012-06-15T07:14:33.760 回答