Dbix:: Класс медленного ответа
У меня есть запрос DBIx::Class, который занимает слишком много времени для выполнения.
Все приведенные ниже SQL были сгенерированы DBIx::Class.
Первый сценарий (простой выбор DBIx):
SELECT me.pf_id, me.origin_id, me.event_time, me.proto_id FROM pf me ORDER BY event_time DESC LIMIT 10;
Время запроса DBIx: 0.390221с (нормально)
Второй сценарий (DBIx Простой выбор с использованием где):
SELECT me.pf_id, me.origin_id, me.event_time, me.proto_id FROM pf me WHERE ( proto_id = 7 ) ORDER BY event_time DESC LIMIT 10;
Время запроса DBIx: 29.27025 с!:(
Третий сценарий (использование pgadmin3 для выполнения запроса выше):
SELECT me.pf_id, me.origin_id, me.event_time, me.proto_id FROM pf me WHERE ( proto_id = 7 ) ORDER BY event_time DESC LIMIT 10;
Время запроса Pgadmin: 25 мс (нормально)
Тот же запрос выполняется довольно быстро с использованием pgdamin.
Некоторая информация:
- Катализатор 5.90091
- DBIx:: Класс 0.082820 (последний)
- Postgres 9.1
- Я сделал все тесты на локальном хосте, используя внутренний сервер Catalyst.
- У меня нет проблем с любой другой комбинацией таблицы / столбца, это специфично для proto_id.
- Схема базы данных автоматически генерируется DBIx::Class::Schema::Loader
определение proto_id:
"proto_id", {data_type => "smallint", is_foreign_key => 1, is_nullable => 0},
Кто-нибудь знает, почему DBIx так долго выполняет этот простой запрос?
Редактировать 1: столбец использует индекс (btree).
Редактировать 2: Это секционированная таблица, я проверяю, все ли вложенные таблицы имеют все индексы, но все еще не объясняет, почему один и тот же запрос медленнее в DBIx::Class.
Редактировать 3: я сделал простой скрипт DBIx::Class и получил те же результаты, просто чтобы убедиться, что проблема не в Catalyst Framework.
Редактировать 4: Используя tcpdump, я заметил, что postgres занимает слишком много времени, чтобы ответить, все еще пытаясь...
Редактировать 5: Использование DBI с SQL кажется довольно быстрым, я почти уверен, что это проблема DBIx::Class.
1 ответ
После некоторых тестов я обнаружил проблему:
Когда я делаю запрос с использованием DBI bind_param () (как это делает DBIx::Class), он почему-то становится очень медленным.
SELECT me.pf_id, me.origin_id, me.event_time, me.proto_id FROM pf me WHERE ( proto_id = ? ) ORDER BY event_time DESC LIMIT ?;
my $sth = $dbh->prepare($sql);
$sth->bind_param(1, 80, { TYPE => SQL_INTEGER });
$sth->bind_param(2, 10, { TYPE => SQL_INTEGER });
$sth->execute();
Поэтому после некоторого времени поиска в CPAN я заметил, что мой DBD::Pg устарел (мой плохой). Я скачал исходники из CPAN, скомпилировал и проблема исчезла. Должно быть какая-то ошибка из старых версий.
TL; DR: если у вас проблемы с DBI или DBIx::Class, убедитесь, что драйвер базы данных DBI обновлен.