nhibernate HQL производительность подзапроса - PullRequest
0 голосов
/ 15 декабря 2009

Я написал hql для поддержки подкачки

            string hql = @"select distinct mr 
                       from MediaResource as mr
                        where     mr.Deleted= false
                            and   mr.Type = :typeId";

            SimpleQuery<MediaResource> q = new SimpleQuery<MediaResource>(hql);
            q.SetParameter("typeId", typeId);
            q.SetQueryRange(page * pageSize, pageSize);
            return q.Execute().ToList();

А потом я написал тест для запуска этой функции и получил журнал nhibernate как

 select
    * 
from
    ( select
        distinct mediaresou0_.MediaResourceID as MediaRes1_7_,
    from
        MediaResource mediaresou0_ 
    where
        mediaresou0_.Deleted=0 
        and mediaresou0_.Type=:p0 ) 
where
    rownum <=:p1;
:p0 = 1, :p1 = 10

Что меня касается, так это select * from (select ...) Будет ли это проблема производительности? Можно ли сказать, что Nhibernate должен сгенерировать SQL-оператор для одного запроса?

Ответы [ 2 ]

2 голосов
/ 17 декабря 2009

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

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

Что касается вашего другого вопроса

Можно ли сказать, что Nhibernate должен сгенерировать SQL-оператор для одного запроса?

Я не верю, что NHibernate может быть запущен для неявного генерирования более оптимальных решений, единственный способ изменить это - изменить способ получения этих данных, но я не вижу проблем с подзапросом сам :)

1 голос
/ 15 декабря 2009

Потеря производительности, вероятно, не будет заметна, если у вас нет большого количества записей. В этом случае вы отзовете все записи, а затем заберете то, что хотите.

Альтернатива - использовать что-то вроде этого:

 SimpleQuery<MediaResource> q = new SimpleQuery<MediaResource>(hql);
        q.SetParameter("typeId", typeId);
        q.SetFirstResult(page * pageSize).SetMaxResults(pageSize);
        return q.Execute().ToList();

SetFirstResult будет делать так, как он говорит - он устанавливает индекс, по которому результаты выбираются при продвижении вперед.

SetMaxResults затем работает на этом и получает количество строк в размере страницы. (фактически sql top, где id> xx)

...