Subject | Re: [firebird-support] Adding second sort column slows down sorting 100-fold |
---|---|
Author | Ann W. Harrison |
Post date | 2010-10-06T22:08:05Z |
On 10/6/2010 5:06 PM, Alec Swan wrote:
many rows the query would select without the "FIRST" clause?
If it's a lot more than 1000, then the problem is that
Firebird can't walk two indexes at once, so ordering by two
fields with separate indexes requires that it retrieve all
the qualifying rows, sort them, then throw out all the rows
it selected after the first 1000.
If you were selecting all the rows that qualify, then you'd
get better performance from the second plan because its faster
to read rows in storage order and sort them than it is to read
them in index order. But reading a lot of stuff you don't
need is a great waste of time, so when you're returning a
subset of the records you select, walking an index is faster.
If both ordering fields were in the same table, you could
use a compound index. But they aren't.
Good luck,
Ann
>Slow ...
> I have a query which joins several tables and then sorts on two
> fields. Both fields have ascending indexes declared on them. It takes
> over 10 seconds to run this query. If I remove the second sort
> criterion, then the query runs 100 times faster. The query plans for
> both queries are shown below.
> PLAN SORT (JOIN (PHYSICAL_COPY INDEX (IDX_cF3Z9NMr/P8YkbENbAJVkA==),Fast ...
> COPY_CLASSIFICATION INDEX (IDX_soqMJd+Yux0RNvCbmE9rrg==),
> PROJECT_CODE_DESCRIPTOR INDEX (IDX_lEwvSCR+VZpQCfw5Duxo0A==), PROJECT
> INDEX (PK_f3m9slJ+02gL6hFClhrZvg==), COPY INDEX
> (PK_ZM6SRonqR8AHSQuCISgvnQ==)))
> PLAN JOIN (PHYSICAL_COPY ORDER IDX_PHYSICAL_COPY_SIZE_ASC INDEXThe "SELECT FIRST 1000 *" is interesting. Do you know how
> (IDX_cF3Z9NMr/P8YkbENbAJVkA==), COPY_CLASSIFICATION INDEX
> (IDX_soqMJd+Yux0RNvCbmE9rrg==), PROJECT_CODE_DESCRIPTOR INDEX
> (IDX_lEwvSCR+VZpQCfw5Duxo0A==), PROJECT INDEX
> (PK_f3m9slJ+02gL6hFClhrZvg==), COPY INDEX
> (PK_ZM6SRonqR8AHSQuCISgvnQ==))
>
many rows the query would select without the "FIRST" clause?
If it's a lot more than 1000, then the problem is that
Firebird can't walk two indexes at once, so ordering by two
fields with separate indexes requires that it retrieve all
the qualifying rows, sort them, then throw out all the rows
it selected after the first 1000.
If you were selecting all the rows that qualify, then you'd
get better performance from the second plan because its faster
to read rows in storage order and sort them than it is to read
them in index order. But reading a lot of stuff you don't
need is a great waste of time, so when you're returning a
subset of the records you select, walking an index is faster.
If both ordering fields were in the same table, you could
use a compound index. But they aren't.
Good luck,
Ann