Помогите ускорить запрос, пожалуйста

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Vas
Сообщения: 22
Зарегистрирован: 31 мар 2005, 19:12

Помогите ускорить запрос, пожалуйста

Сообщение Vas » 10 авг 2006, 13:08

Запрос выполняется очень долго. Где подкрутить ?

Код: Выделить всё

SELECT
    *
FROM
    DOC H
    JOIN POS P ON H.ID=P.DOC_ID
    JOIN POST PN ON PN.POS_ID=P.ID
WHERE
    P.PRODUCT_ID=50306032
    AND H.DOC_DATE>='09.07.2006'
    AND H.DOC_DATE<='today'
    AND H.DOC_TYPE IN (3, 9)
План
PLAN JOIN (P INDEX (RDB$FOREIGN121),PN INDEX (RDB$36),H INDEX (IDX_DOC_DATE_DESC,IDX_DOC_DATE,RDB$PRIMARY27,RDB$FOREIGN46,RDB$FOREIGN46))

Адаптированный план
PLAN JOIN (P INDEX (FK_PRODUCT_ID),PN INDEX (UNI_POS_ID),H INDEX (IDX_DOC_DATE_DESC,IDX_DOC_DATE,PRI_DOC,FK_DOC_TYPE,FK_DOC_TYPE))

------ Performance info ------
Prepare time = 16ms
Execute time = 7s 734ms
Avg fetch time = 1 933.50 ms
Current memory = 157 734 813
Max memory = 158 260 739
Memory buffers = 35 828
Reads from disk to cache = 0
Writes from cache to disk = 0
Fetches from cache = 71 650

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 10 авг 2006, 13:13

Убей IDX_DOC_DATE_DESC.

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 10 авг 2006, 13:22

По-моему у него вообще слишком много индексов используется в запросе... Я бы посоветовал переписать запрос с использованием Left Join. Здесь таблица DOC приджойнивается последней, а значит, там дополнительный отсев идет уже после приджойнивания PN, что скорости не прибавляет.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 10 авг 2006, 13:27

Самое быстрое - когда по одному индексу всё работает, конечно, высокой селективности.
Напиши статистику по индексам, без этого трудно сказать.

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 10 авг 2006, 13:33

И еще: отбор по дате сделай через BETWEEN. На одно условие меньше в итоге.

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: Помогите ускорить запрос, пожалуйста

Сообщение hvlad » 10 авг 2006, 14:23

Попробуй

Код: Выделить всё

SELECT  *
FROM
    DOC H
    JOIN POS P ON H.ID +0 =P.DOC_ID
    JOIN POST PN ON PN.POS_ID=P.ID
WHERE
    P.PRODUCT_ID=50306032
    AND H.DOC_DATE>='09.07.2006'
    AND H.DOC_DATE<='today'
    AND H.DOC_TYPE +0 IN (3, 9)
или

Код: Выделить всё

SELECT  *
FROM
    DOC H
    JOIN POS P ON H.ID =P.DOC_ID
    JOIN POST PN ON PN.POS_ID=P.ID
WHERE
    P.PRODUCT_ID=50306032
    AND H.DOC_DATE+0 >='09.07.2006'
    AND H.DOC_DATE+0 <='today'
    AND H.DOC_TYPE +0 IN (3, 9)

Vas
Сообщения: 22
Зарегистрирован: 31 мар 2005, 19:12

Сообщение Vas » 10 авг 2006, 15:47

hvlad - второй запрос помог. Спасибо большое.
Время выполнения - 188мс
Оптимизатор, как всегда, радует.

Индексы убивать не хотелось, чтоб в другом месте тормоз не вылез.
битвин пробовал, не помогает.
менять местами таблицы, писать им лэфт джойн тоже не помогало ( каждый раз это делаю, достало уже)

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 10 авг 2006, 16:14

Дело не в оптимизаторе. Ты лучше скажи, зачем тебе два индекса по дате?
P.S. Бетвин и не поможет шибко. Просто это хороший стиль написания запросов. И тебе, и серверу понятно, что делаешь выборку по диапазону.

Vas
Сообщения: 22
Зарегистрирован: 31 мар 2005, 19:12

Сообщение Vas » 10 авг 2006, 17:20

Индекс этот, мне в том запросе не за чем, впрочем как и другие индексы, которые используются в обычном запросе ( без +0), правда на них на всех констрейнты разные весят (типа форейн кий) А вот в каком-нибудь другом еще кому-нибудь они, может, и понадобятся.
С битвином согласен.
Про оптимизатор спорить не буду. Если Вы считаете, что танцы с отрубанием индексов вроде +0, лэфт джойн там, где нужен иннер и перестановка таблиц местами в запросе должен делать человек, то спорить не буду.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 10 авг 2006, 17:30

Vas писал(а):А вот в каком-нибудь другом еще кому-нибудь они, может, и понадобятся
Не создавай объектов "а вдруг пригодятся", если у тебя нет готового плана, как оно будет в будущем. Индекс создать никогда не поздно, если он вдруг позарез понадобится. А так только базу засоряет.
Vas писал(а):Про оптимизатор спорить не буду. Если Вы считаете, что танцы с отрубанием индексов вроде +0, лэфт джойн там, где нужен иннер и перестановка таблиц местами в запросе должен делать человек, то спорить не буду.
Ты же запрос пишешь, а не сервер за тебя. Значит и должен указать серверу максимально доступно, что ты хочешь. Я пишу +0 всегда, даже если такого индекса нет. Во-первых, потому что это позволяет лучше в голове построить план, а во-вторых, никаких двояких толкований у сервера не возникнет никогда, хоть я там десять индексов для других целей нацеплю.

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 10 авг 2006, 17:48

Vas писал(а):Оптимизатор, как всегда, радует
На 2-ке пробовал ?

Vas
Сообщения: 22
Зарегистрирован: 31 мар 2005, 19:12

Сообщение Vas » 11 авг 2006, 14:43

hvlad
Конкретно это не пробовал, т.к. есть определенные проблемы с миграцией. Но вообще кое-что погонял, и результат очень впечатлил. На некоторых тяжелых отчетах выигрыш в десятки раз.
Речь, о той же самой базе.

Ответить