Subject inner join index optimization problem
Author officialz
I have an optimization problem where (it seems) I can't force the
optimizer to use an index for a inner join on FB 2.0.3

CREATE TABLE PROPERTY_VALUE(
ID Numeric(18,0) NOT NULL,
PROPERTY_VALUE Varchar(1024) CHARACTER SET OCTETS NOT NULL,
PRIMARY KEY (ID),
UNIQUE (PROPERTY_VALUE)
);
CREATE TABLE PROPERTY_VALUE_LIST(
PROPERTY_ID Numeric(18,0) NOT NULL,
PROPERTY_VALUE_ID Numeric(18,0) NOT NULL,
COMPONENT_ID Numeric(18,0) NOT NULL
);
ALTER TABLE PROPERTY_VALUE_LIST ADD
FOREIGN KEY (PROPERTY_ID) REFERENCES PROPERTY (ID);
ALTER TABLE PROPERTY_VALUE_LIST ADD
FOREIGN KEY (PROPERTY_VALUE_ID) REFERENCES PROPERTY_VALUE (ID);
ALTER TABLE PROPERTY_VALUE_LIST ADD
FOREIGN KEY (COMPONENT_ID) REFERENCES COMPONENT (ID);

property_value has 12,000 rows
property_value_list has 25,000,000

Using the sample query:

SELECT pvl.component_id, pvl.property_id, pv.property_value as
property_value
FROM property_value pv, property_value_list pvl
WHERE pvl.system_id = 8413 AND pvl.test_script_id = 67919 AND
pv.id=pvl.property_value_id
ORDER BY pvl.component_id, pvl.property_id, pvl.property_value_id

this uses the plan PLAN SORT (JOIN (PV NATURAL, PVL INDEX
(RDB$FOREIGN70, RDB$FOREIGN73, RDB$FOREIGN72)))

I would expect it to use the plan
PLAN SORT (JOIN (PV INDEX(RDB$PRIMARY39), PVL INDEX (RDB$FOREIGN70,
RDB$FOREIGN73, RDB$FOREIGN72)))
where
RDB$FOREIGN70 = pvl.PROPERTY_VALUE_ID
RDB$FOREIGN73 = pvl.SYSTEM_ID
RDB$FOREIGN72 = pvl.TEST_SCRIPT_ID
RDB$PRIMARY39 = pv.property_value.id

However when i try to force it to use that plan:
SELECT pvl.component_id, pvl.property_id, pv.property_value as
property_value
FROM property_value pv, property_value_list pvl
WHERE pvl.system_id = 8413 AND pvl.test_script_id = 67919 AND
pv.id=pvl.property_value_id
PLAN SORT
(JOIN (PV INDEX(RDB$PRIMARY39), PVL INDEX (RDB$FOREIGN70,
RDB$FOREIGN73, RDB$FOREIGN72)))
ORDER BY pvl.component_id, pvl.property_id, pvl.property_value_id

I get
Message: isc_dsql_prepare failed

SQL Message : -284
index cannot be used in the specified plan

Engine Code : 335544642
Engine Message :
index RDB$PRIMARY39 cannot be used in the specified plan

I would like to know why it does not want to use the index on the pv.id

Then again, if I use:
SELECT pvl.component_id, pvl.property_id, pv.property_value as
property_value
FROM property_value pv, property_value_list pvl
WHERE pvl.system_id = 8413 AND pvl.test_script_id = 67919 AND
pv.id=pvl.property_value_id AND pv.id>0
ORDER BY pvl.component_id, pvl.property_id, pvl.property_value_id

It uses the plan:
PLAN SORT (JOIN (PV INDEX (RDB$PRIMARY39), PVL INDEX (RDB$FOREIGN70,
RDB$FOREIGN73, RDB$FOREIGN72)))

The plan looks ok, but it takes just as long to run.

The plan using the pv natural and the one using PV INDEX
(RDB$PRIMARY39) - with the pv.id>0 hack - take 6 secs. to run on a
core duo 2.4ghz, fb 2.0.3 windows superserver
I need to make sure the query is optimized. The end result table only
has 233 rows, and so is the case with

SELECT pvl.component_id, pvl.property_id
FROM property_value_list pvl
WHERE pvl.system_id = 8413 AND pvl.test_script_id = 67919

The query above is basically one of the two tables I want to join (the
other, obviosly is the property_value). This query above completes
instantly with 233 rows.

Now, I can "manually" force the join in this way, using a subquery:

select * from
(SELECT pvl.component_id, pvl.property_id, pvl.PROPERTY_VALUE_ID
FROM property_value_list pvl
WHERE pvl.system_id = 8413 AND pvl.test_script_id = 67919) as pvls
inner join PROPERTY_VALUE on (PROPERTY_VALUE.id =
pvls.property_value_id);
This uses: PLAN JOIN (PROPERTY_VALUE NATURAL, PVLS PVL INDEX
(RDB$FOREIGN70, RDB$FOREIGN73, RDB$FOREIGN72))

This takes TWO MINUTES (note the PROPERTY_VALUE NATURAL)

If, however, I use the much faster

select * from
(SELECT pvl.component_id, pvl.property_id, pvl.PROPERTY_VALUE_ID
FROM property_value_list pvl
WHERE pvl.system_id = 8413 AND pvl.test_script_id = 67919) as pvls
left join PROPERTY_VALUE on (PROPERTY_VALUE.id = pvls.property_value_id)
This uses: PLAN JOIN (PVLS PVL INDEX (RDB$FOREIGN73, RDB$FOREIGN72),
PROPERTY_VALUE INDEX (RDB$PRIMARY39))

This result table is ready INSTANTLY - and yes, it is using the
RDB$PRIMARY39 index. =\

I don't have much experience optimizing FB queries (yet) so if
somebody can throw some light on this behavior, it will be greatly
appreciated.