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