As Karol writes, introducing a descending index on the ID field ought to make your query quick (Firebird indices - and keys - are unidirectional).

Firebird has never been good with IN(<subselect>), I was bitten around 1999, changed to using EXISTS and for the last 20 years I have never missed IN(<subselect>) (and NOT IN is worse than IN) and it does take time to consider 324 million tuples (18000*18000).

Your particular query I would have rewritten:

select ID
from TBL_TEST
order by ID desc
rows 3 to 10

but as you write, it is a simplified statement, so

select first 8 t1.ID
from TBL_TEST t1
join TBL_TEST t2 on t1.ID < t2.ID
join TBL_TEST t3 on t2.ID < t3.ID
order by t1.ID desc

or

select first 8 t1.ID
from TBL_TEST t1
where exists( select *
              from TBL_TEST t2
              join TBL_TEST t3 on t2.ID < t3.ID
              where t1.ID < t2.ID )
order by t1.ID desc

or even

execute block returns( ID integer )
as
declare variable ID1 integer;
declare variable ID2 integer;
begin
  for select first 2 ID
  from TBL_TEST
  order by ID desc
  into :ID2 do
    if ( ID1 is null ) then
      ID1 = ID2;
  for select ID
  from TBL_TEST
  where ID not in (:ID1, :ID2) -- not in is OK when used with constants, just avoid subselects
  order by ID desc
  do
    suspend;
end

may be more appropriate starting points for fixing your real query if your not satisfied with creating a descending index.

I know nothing about Firebird 2.1.3, maybe that particular version contains changes that speeds up simple cases like yours but with side effects that made the developers remove this change later. I just know that Firebird 0.9.4 convinced me to shun away from (NOT) IN (<subselect>).

HTH,
Set

Den 25.01.2020 07:59, skrev Matthias Winkler spmm...@gmail.com [firebird-support]:


Thanks for all your replies:

The major problem is, that with firebird 2.1.3 the query also completes within 3 seconds. Something seems to have changed with the optimizer, execution plan or whatever (~ sorry I dont know the terms here)
related to sorting, or double sorting, or sorting within "sub"-queries.

BR

Matthias





On Fri, Jan 24, 2020 at 3:53 PM Karol Bieniaszewski liviusliv...@poczta.onet.pl <mailto:liviusliv...@poczta.onet.pl> [firebird-support] <firebird-support@yahoogroups.com <mailto:firebird-support@yahoogroups.com>> wrote:

    Hi

          „select first(8) ID from TBL_TEST

          where ID not in (select first(2) ID from TBL_TEST order by
    ID desc)

          order by ID desc”

    few things:

    Just hint but „first” is not function First(8) is same as First 8 😉

    You should avoid NOT IN queries and use EXISTS/NOT EXISTS instead.
    But if you really need it then such subquery should be well indexed.


    >> „Is there a way to force limiting the result set before sorting
    it?”

    Create descending index on ID column, than this subquery will go
    throught index without sorting.

    It will be instant i suppose

    Regards,

    Karol Bieniaszewski


      • ... Gabor Boros mlngl...@bgss.hu [firebird-support]
      • ... Dimitry Sibiryakov s...@ibphoenix.com [firebird-support]
        • ... Matthias Winkler spmm...@gmail.com [firebird-support]
          • ... Dimitry Sibiryakov s...@ibphoenix.com [firebird-support]
            • ... Matthias Winkler spmm...@gmail.com [firebird-support]
              • ... Dimitry Sibiryakov s...@ibphoenix.com [firebird-support]
        • ... Mark Rotteveel m...@lawinegevaar.nl [firebird-support]
          • ... Dimitry Sibiryakov s...@ibphoenix.com [firebird-support]
            • ... Karol Bieniaszewski liviusliv...@poczta.onet.pl [firebird-support]
              • ... Matthias Winkler spmm...@gmail.com [firebird-support]
              • ... setysvar setys...@gmail.com [firebird-support]
              • ... Dimitry Sibiryakov s...@ibphoenix.com [firebird-support]
              • ... Matthias Winkler spmm...@gmail.com [firebird-support]
  • Re: [fi... Elmar Haneke el...@haneke.de [firebird-support]

Reply via email to