Hello, Dmitry!
You wrote  on Thu, 11 Sep 2008 15:11:23 +0400:

>> TABLE_BIG = 2млн (PG)
>> TABLE_SMALL = 2тыс (SA)
>> TABLE_MEDIUM = 20тыс (PSG)

DY> Я бы хотел взглянуть на эту базу.
DY> Ибо 2.1 не должен был выбрать такой плохой план.

Оригинальная бд не моя, и весит 30гиг...
Попытался повторить это на тестовой БД - с трудом, но вроде получилось.
http://rapidshare.com/files/144380650/TEST.rar.html  30МБ


Тестил запросом

select
 sum(pg.debit), count(distinct sa.id_small)
from small_table sa
join big_table pg on pg.id_small=sa.id_small
join medium_table psg on psg.id_medium=pg.id_medium
where sa.id_fk_1=:sdf

BIG_TABLE  - pg 1,8 млн записей
SMALL_TABLE  - sa 1,8 тыс
MEDIUM_TABLE - psg 16 тыс

PLAN JOIN (PSG NATURAL, PG INDEX (BIG_TABLE_IDX2), SA INDEX (SMALL_TABLE_IDX1))



Кстати, добиться такого плана получилось только после заполнения ( update small_table t set t.id_fk_1=567 ) поля в маленькой таблице, когда оно было пустое(null во всех записях) - то план выбрался

PLAN JOIN (SA NATURAL, PG INDEX (BIG_TABLE_IDX1), PSG INDEX (PK_MEDIUM_TABLE))


CREATE TABLE BIG_TABLE (
   ID_SMALL   INTEGER NOT NULL,
   ID_MEDIUM  INTEGER NOT NULL,
   DEBIT      NUMERIC(5,2) NOT NULL,
   ID_FK_1    INTEGER NOT NULL -- случайные данные
);


CREATE TABLE MEDIUM_TABLE (
   ID_MEDIUM  INTEGER NOT NULL
);


CREATE TABLE SMALL_TABLE (
   ID_SMALL  INTEGER NOT NULL,
   ID_FK_1   INTEGER NOT NULL -- случайные данные
);

ALTER TABLE MEDIUM_TABLE ADD CONSTRAINT PK_MEDIUM_TABLE PRIMARY KEY (ID_MEDIUM);

CREATE INDEX BIG_TABLE_IDX1 ON BIG_TABLE (ID_SMALL, ID_MEDIUM);
CREATE INDEX BIG_TABLE_IDX2 ON BIG_TABLE (ID_MEDIUM, ID_FK_1);

CREATE INDEX SMALL_TABLE_IDX1 ON SMALL_TABLE (ID_SMALL);

--
-=Лечил тyт одного то желтyхи, недолечил - помеp он. а как вскpыли - оказалось, китаец..=- With best regards, Nikolay Ponomarenko

Ответить