Страница 1 из 2
Как ускорить отклик сервера на запрос данных?
Добавлено: 05 дек 2007, 19:59
ArtDen
Ситуация такая. Приходиться выбирать большой объём данных (250 000 строк и более) из больших таблиц (> 64 столбцов). Из двух таблиц путём их перемножения выбирается данные по индексным полям. План запроса следующий:
Код: Выделить всё
PLAN JOIN (RECORDS ORDER RECORDS_ID_INDEX INDEX (RECORDS_TYPE_INDEX, RECORDS_RACE_INDEX), REC_VALUES INDEX (REC_VALUES_ID_INDEX))
Не устраивает скорость между запросом и приходим первой порцией данных с сервера. В этот период сервак долго шелестит винчестером практически без загрузки процессора. Если то-же самый запрос повторить сразу после прошлого запроса, то сервер откликается практически сразу. Но стоит сделать несколько запросов из разных участков таблицы, как время отклика опять увеличивается.
Я так понимаю, что это происходит из-за того, что всё время сервер не держит индексы в памяти, подгружая/выгружая их по мере необходимости. Можно как-то заставить сервер держать индексы в памяти всё время? Или хотя бы задать приоритет для индексов перед обычными данными, которые кешируются в памяти? И вообще, правильно ли я представляю проблему и дело вообще не в индексах, а в чём-то другом?
Добавлено: 05 дек 2007, 20:14
WildSery
Возможных причин слишком много, чтобы сказать "проблема тут".
Во-первых, ты не указал версию сервера.
Во-вторых, запроса.
Можно предположить так с ходу, что запрос слишком долго в порядке индекса идёт до собственно данных, занимается ненужной работой.
В общем, давай запрос.
Re: Как ускорить отклик сервера на запрос данных?
Добавлено: 05 дек 2007, 20:23
stix-s
ArtDen писал(а):Ситуация такая. Приходиться выбирать большой объём данных (250 000 строк и более) из больших таблиц (> 64 столбцов). Из двух таблиц путём их перемножения выбирается данные по индексным полям. План запроса следующий:
Код: Выделить всё
PLAN JOIN (RECORDS ORDER RECORDS_ID_INDEX INDEX (RECORDS_TYPE_INDEX, RECORDS_RACE_INDEX), REC_VALUES INDEX (REC_VALUES_ID_INDEX))
Не устраивает скорость между запросом и приходим первой порцией данных с сервера. В этот период сервак долго шелестит винчестером практически без загрузки процессора. Если то-же самый запрос повторить сразу после прошлого запроса, то сервер откликается практически сразу. Но стоит сделать несколько запросов из разных участков таблицы, как время отклика опять увеличивается.
Я так понимаю, что это происходит из-за того, что всё время сервер не держит индексы в памяти, подгружая/выгружая их по мере необходимости. Можно как-то заставить сервер держать индексы в памяти всё время? Или хотя бы задать приоритет для индексов перед обычными данными, которые кешируются в памяти? И вообще, правильно ли я представляю проблему и дело вообще не в индексах, а в чём-то другом?
в кэш поди кидает,навена и сортировка присутствует
, а кому из клиентов понадобилось поглядеть разом на 250 тыс строк?
Добавлено: 05 дек 2007, 20:38
ArtDen
WildSery писал(а):Во-первых, ты не указал версию сервера.
Извиняюсь. FB 2.0.3, WinXP SP2
WildSery писал(а):Во-вторых, запроса.
Запрос создаётся программно, но сейчас попробую воспроизвести. Вот частный случай запроса (просьба не смеяться

):
Код: Выделить всё
SELECT records.id_mk, records.race, records.rec_time, records.time_offset, records.depth_z, records.depth_cur, records.depth_lag, records.operation ,
rec_values.p01, rec_values.v01,
rec_values.p02, rec_values.v02,
rec_values.p03, rec_values.v03,
rec_values.p04, rec_values.v04,
... ,
rec_values.p32, rec_values.v32
FROM records, rec_values
WHERE records.id_mk=rec_values.id_records AND records.race IN (52,53,141 ) AND records.rec_type=1
ORDER BY records.id_mk;
В принципе, ORDER BY records.id_mk лишнее, т.к. записи в таблице гарантировано располагаются в порядке возрастания records.id_mk, но если убрать ORDER BY records.id_mk, то это не сильно меняет ситуацию.
Re: Как ускорить отклик сервера на запрос данных?
Добавлено: 05 дек 2007, 20:41
ArtDen
stix-s писал(а):а кому из клиентов понадобилось поглядеть разом на 250 тыс строк?
Эти данные после запроса визуализируются в виде графиков кривых на экране. Так что количество данных - тут оправдано
Добавлено: 05 дек 2007, 21:55
Merlin
Не включая мозг: для начала грохнуть или просто заблокировать в запросе индекс по RECORDS_TYPE_INDEX. Там к бабке не ходи пять с половиною значений на все двестипсят тыщ записей. Дальше смотреть статистику индекса RECORDS_RACE_INDEX, может и его фтопку.
Добавлено: 05 дек 2007, 21:59
kdv
Добавлено: 05 дек 2007, 22:04
Merlin
Вроде Влад с Димой били себя пяткой в грудь, что IN в двойке не настолько ресурсоёмок, как раньше. Скока там рас, правда, трудно сказать, в отличие от типов

Вроде больше 100, должно быть ничо, ежели распределены равномерно. Вот если узким пиком, тады да, только внутри него индекс полезен.
Добавлено: 05 дек 2007, 22:39
kdv
раньше для in использовалось столько "индексов", сколько было значений в перечислении. потом в YA и теперь в FB 2 для этого используется только один индекс. Но сканов индекса, как я понимаю, сколько было столько и осталось. Так что, небольшая экономия памяти и скорости. Проявляется сильно, на мой взгляд, когда значений в in указано поболе 4-5, ну и от количества разных значений в индексе тоже зависит.
Добавлено: 05 дек 2007, 23:34
hvlad
Я бы первым делом убил индекс в ORDER BY. Он полезен, только если выбирается мало записей
Добавлено: 06 дек 2007, 00:54
kdv
ну так видишь, ему не нравится что первая порция медленно выдается. а при сортировке если там дофига записей первая порция точно будет с задержкой.
Добавлено: 06 дек 2007, 09:44
ArtDen
Merlin писал(а):Дальше смотреть статистику индекса RECORDS_RACE_INDEX, может и его фтопку.
А насколько маленькой должна быть статистика, чтобы убрать индекс?
Добавлено: 06 дек 2007, 09:45
ArtDen
Добавлено: 06 дек 2007, 10:12
stix-s
ArtDen писал(а):
А что это может дать?
отмену использования индекса по данному полю
ты что-либо пробовал?
Добавлено: 06 дек 2007, 10:24
ArtDen
hvlad писал(а):Я бы первым делом убил индекс в ORDER BY. Он полезен, только если выбирается мало записей
Хм... Выяснилось, что мой индекс для records.id_mk полностью дублирует индекс, созданный самим FB для основного ключа. Задизаблил я свой индекс и время отклика сразу уменьшилось. Правда, после этого я сделал для него енабле, а время отклика осталось таким-же маленьким. Короче, чудеса

Добавлено: 06 дек 2007, 10:32
ArtDen
stix-s писал(а):отмену использования индекса по данному полю
ты что-либо пробовал?
Попробовал records.race+0 IN . До сих пор жду ответа от сервера

Другими словами время отклика увеличилось на несколько порядков
Добавлено: 06 дек 2007, 12:33
kdv
Правда, после этого я сделал для него енабле
нахрена?
Попробовал records.race+0 IN . До сих пор жду ответа от сервера
тогда ты как-нибудь сам разбирайся. прочитай про методы доступа, про оптимизацию запросов, и т.п.
Добавлено: 06 дек 2007, 12:39
WildSery
ArtDen писал(а):Правда, после этого я сделал для него енабле, а время отклика осталось таким-же маленьким. Короче, чудеса

Посмотри ещё раз план. Если там по-другому стало, значит, пересчиталась статистика индекса.
И вообще, обнови статистику индексов.
Добавлено: 06 дек 2007, 13:42
ArtDen
kdv писал(а):нахрена?
Чтобы убедиться, что дело было именно в этом индексе. Сейчас я его вообще удалил.
kdv писал(а):тогда ты как-нибудь сам разбирайся. прочитай про методы доступа, про оптимизацию запросов, и т.п.
Не совсем понял твой ответ. Я сказал, что с запросом records.race+0 IN работает гораздо дольше, чем с records.race IN, что подтверждает, что индекс по records.race необходим. Или я что-то не понимаю?
Добавлено: 06 дек 2007, 14:01
ArtDen
WildSery писал(а):Посмотри ещё раз план. Если там по-другому стало, значит, пересчиталась статистика индекса.
План стал таким:
Код: Выделить всё
PLAN JOIN (RECORDS ORDER RDB$PRIMARY2 INDEX (RECORDS_RACE_INDEX, RECORDS_TYPE_INDEX), REC_VALUES INDEX (REC_VALUES_ID_INDEX))
Т.е. поменялись местами RECORDS_RACE_INDEX и RECORDS_TYPE_INDEX