При этом вызов Open() для Select = "SELECT * FROM Table_name" занимает меньше секунды, а проход по записям при помощи MoveNext() — секунд 40. Это устраивает.
Теперь встала задача получить количество записей в запросе. У Open'а среди параметров есть DBROWCOUNT* pRowsAffected,
куда это количество записывается. Однако простой вызов
При этом в RowsAffected успешно записывается кол-во записей, но этот вызов Open() выполняется 12 сек, а сам проход по записям работает раз в 15 медленнее предыдущего варианта. Что неприемлимо.
Просмотрел много сообщений и на здешнем форуме, и в гугле искал — все спрашивают, как получить кол-во записей, но никто не волновался о скорости последующего прохода.
Знает кто-нибудь, как получить кол-во записей в запросе и не потерять в скорости ?
Заранее благодарю.
Re: [OLEDB ] Количество записей в запросе и жуткие тормоза
Здравствуйте, Nonmanual Worker, Вы писали:
NW>А выполнить запрос SELECT count(*) FROM Table_name идеология не позволяет?
Собственно, этот запрос был представлен в качестве примера, чтобы просто оценить скорость работы.
Реально запросы будут разные и намного сложнее, поэтому парсить их самому и приделывать к ним COUNT я не собираюсь.
Re[3]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Здравствуйте, andy_84, Вы писали:
_>Собственно, этот запрос был представлен в качестве примера, чтобы просто оценить скорость работы. _>Реально запросы будут разные и намного сложнее, поэтому парсить их самому и приделывать к ним COUNT я не собираюсь.
Но видимо прийдется. Я немного представляю, как работают сервера баз данных (правда не конкретно про SQL Server), и скорее всего тормоза не получится победить (затык будет или на обработке сервером запроса, или при выборке данных клиентом). Да, кстати, еще посмотрите потребление памяти клиентом при установленном DBPROP_CANHOLDROWS и без него.
Но главный запрос такой: Зачем вам нужно знать сколько записей возвращается? Не для того ли, что прогресс нарисовать?
Re: [OLEDB ] Количество записей в запросе и жуткие тормоза
Здравствуйте, Nonmanual Worker, Вы писали:
NW>Да, кстати, еще посмотрите потребление памяти клиентом при установленном DBPROP_CANHOLDROWS и без него. Но главный запрос такой: Зачем вам нужно знать сколько записей возвращается? Не для того ли, что прогресс нарисовать?
На потреблении памяти не сказывается.
Да, действительно, мне нужно сделать прогресс
Re: [OLEDB ] Количество записей в запросе и жуткие тормоза
andy_84 wrote:
> Теперь встала задача получить количество записей в запросе. У Open'а > среди параметров есть DBROWCOUNT* pRowsAffected, > куда это количество записывается. Однако простой вызов > > HRESULT hr = command.Open(Session, Select, 0, &RowsAffected); > > > Пишет в RowsAffected -1, означающий, что "The number of affected rows is > not available" (с) MSDN. Хорошо, пробуем сделать например так
Это -- старая фича. В реляционных СУБД невозможно вообще
получить кол-во строк, которые возвращает запрос.
Чтобы его получить, вы должны прочитать все строки.
И посчитать их. Именно это и делает внутри OLEDB (или другие API).
Так что просто меняйте подход -- выполняйте запрос, получайте
данные, потом считайте строки и обрабатывайте их.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: [OLEDB ] Количество записей в запросе и жуткие тормоз
_>Собственно, этот запрос был представлен в качестве примера, чтобы просто оценить скорость работы. _>Реально запросы будут разные и намного сложнее, поэтому парсить их самому и приделывать к ним COUNT я не собираюсь.
Парсить не нужно, а приделывать очень просто.
SELECT COUNT(*) FROM (<any query>) A
Оптимизатор любой адекватной СУБД это проглотит.
Re[2]: [OLEDB ] Количество записей в запросе и жуткие тормоз
MZ>Это -- старая фича. В реляционных СУБД невозможно вообще MZ>получить кол-во строк, которые возвращает запрос.
Это не совсем так, во многие СУБД могут определить количество строк не выполняя выборки как таковой. Это делается еще на этапе оптимизации запроса. Количество может быть определена по индексу (если есть условие), статистике (если выборка по полной таблице) и прочие варианты.. иногда количество может быть определено не точно с последующим уточнением. Все зависит от крутизны СУБД. Во многих случаях запросы типа SELECT COUNT(*) FROM (<some query>) as A могут быть выполнены без реального выполнения <some query>
Re[3]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Disappear wrote:
> Это не совсем так, во многие СУБД могут определить количество строк не > выполняя выборки как таковой.
Нет, невозможно, вы ошибаетесь.
Это делается еще на этапе оптимизации > запроса. Количество может быть определена по индексу (если есть > условие), статистике (если выборка по полной таблице) и прочие > варианты..
Это — неточное кол-во записей.
Оно даже на самом деле не абсолютное количество записей,
а относительное для разных вариантов планов запросов.
иногда количество может быть определено не точно с > последующим уточнением.
Для уточнения надо было бы выполнить полностью запрос.
Причём если выполнить его ещё раз, уже для получения
данных, это будет другая транзакция, и другое кол-во
записей (и качество тоже).
Все зависит от крутизны СУБД. Во многих случаях > запросы типа SELECT COUNT(*) FROM (<some query>) as A могут быть > выполнены без реального выполнения <some query>
ага, ну да, у "крутых" СУБД есть такая волшебная палочка,
вот она раз! как взмахнёт ею, и — пожалуйста, уже знает
кол-во записей !
Posted via RSDN NNTP Server 2.1 beta
Re[2]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Так вот после второго вызова hr == S_OK, а m_RowCount равно 0, при том что первый запрос вернул отличное от 0 число записей. Может я не учел эти самые тонкости?
Попробую сейчас сделать через IMultipleResults, мож че получится
Re[4]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Здравствуйте, Disappear, Вы писали:
D>Парсить не нужно, а приделывать очень просто. D>SELECT COUNT(*) FROM (<any query>) A D>Оптимизатор любой адекватной СУБД это проглотит.
Кстати, это хороший вариант.
Присоединюсь, и посоветую andy_84 сделать данным образом.
Re[3]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Здравствуйте, MasterZiv, Вы писали:
MZ>Disappear wrote:
>> Это не совсем так, во многие СУБД могут определить количество строк не >> выполняя выборки как таковой.
MZ>Нет, невозможно, вы ошибаетесь.
По индексу количесто записей известно точно.
Знаю точно, что вот эта СУБД (www.qdtechnology.com) это умеет. Знаю, собственно потому, что сам писал ее оптимизатор.
Уточнение может быть произведено не полной выборкой данных, так как статистика позволяет отсечь ненужные части таблицы. Плюс к этому, нет необходимости считывать некоторые колонки, так как они не идут на выход в случае select count(*) from (some), т.е. по памяти запрос будет работать тоже существенно лучше.
В общем случае — согласен, расчитывать на это не стоит. К примеру у MySQL стандартный оптимизатор достаточно простенький и многого не умеет.
И еще хочу добавить,
SELECT COUNT(*) FROM (<query>) A не отработает если мы имеет query виды <select expr> order by <columns,>. По крайней мере, по стандарту, order by должен всегда быть в конце запроса. Другое дело, что например MS SQL в данном случае уходит от стандарта и позволяет делать order by даже в подзапросах (это там понадобилось для поддержки ключевого слова top, так как top имеет смысл когда порядок записей известен). Но, опять же, в общем случае order by в подзапросах не поддерживается.
Re[5]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Disappear wrote:
> По индексу количесто записей известно точно. > Знаю точно, что вот эта СУБД (www.qdtechnology.com > <http://www.qdtechnology.com>) это умеет. Знаю, собственно потому, что > сам писал ее оптимизатор.
Увы, нет. Далеко не во всех СУБД.
У вас работают разные транзакции, для них видно
разное кол-во записей.
Но вы правы, в вашей СУБД — да.
"QD provides safe 24/7 read-only database access anytime and anywhere."
Ключевое слово — read-only.
Posted via RSDN NNTP Server 2.1 beta
Re[6]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Disappear пишет:
> SELECT COUNT(*) FROM (<query>) A не отработает если мы имеет query виды > <select expr> order by <columns,>. По крайней мере, по стандарту, order > by должен всегда быть в конце запроса. Другое дело, что например MS SQL
MySQL тоже только что проглотил вот такое и даже не поперхнулся. Видимо
по тем же причинам.
SELECT * FROM (
SELECT * FROM `counter_hits` ORDER BY `visitor_ip` LIMIT 10 , 10
) aaa
ORDER BY `datetime` DESC
Disappear wrote:
> А что мешает внутри блокирующей тратзакции сделать то же самое?
Можно. можно заблокировать всю таблицу и радоваться, что у тебя --
фиксированное число строк в таблице. Только вот СУБД все борются
как раз за обратное.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Здравствуйте, Disappear, Вы писали:
>Парсить не нужно, а приделывать очень просто. >SELECT COUNT(*) FROM (<any query>) A >Оптимизатор любой адекватной СУБД это проглотит.
У SQL Server оптимизатор это не проглотил. Я набросал такой запросец, и сидел ждал, пока сервер считал кол-во строк вложенного запроса.
Re[4]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Здравствуйте, Nonmanual Worker, Вы писали:
NW>Здравствуйте, andy_84, Вы писали:
_>>Попробую сейчас сделать через IMultipleResults, мож че получится
NW>Должно получится.
Ну собственно, сделал я через этот IMultipleResults: выполнил "SELECT * FROM Table_name; SELECT @@ROWCOUNT as row_count", вызвал GetNextResult() и сидел ждал, пока не были пройдены все записи, возвращенные первым запросом.
Re[5]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Здравствуйте, andy_84, Вы писали:
_>У SQL Server оптимизатор это не проглотил.
Нет, SQL Server оптимизатор это проглотил, но долго жевал
_>Я набросал такой запросец, и сидел ждал, пока сервер считал кол-во строк вложенного запроса.
Подставьте в свой оригинальный запрос COUNT(*) вместо списка полей, выполните (если выполнится), и сравните с тем временем, что вы получили. Если совпадает — то оптимизатор работает хорошо в силу своих возможностей, если получится что новое время значительно меньше — значит оптимизатор тупит.
З.Ы. Желательно пишите время выполнения запросов.
Re[6]: [OLEDB ] Количество записей в запросе и жуткие тормоз
Здравствуйте, Nonmanual Worker, Вы писали:
NW>Здравствуйте, andy_84, Вы писали:
_>>У SQL Server оптимизатор это не проглотил.
NW>Нет, SQL Server оптимизатор это проглотил, но долго жевал
_>>Я набросал такой запросец, и сидел ждал, пока сервер считал кол-во строк вложенного запроса.
NW>Подставьте в свой оригинальный запрос COUNT(*) вместо списка полей, выполните (если выполнится), и сравните с тем временем, что вы получили. Если совпадает — то оптимизатор работает хорошо в силу своих возможностей, если получится что новое время значительно меньше — значит оптимизатор тупит.
NW>З.Ы. Желательно пишите время выполнения запросов.
Щас еще раз все внимательно проверил — действительно, "SELECT COUNT(*) FROM (<any query>) A" работает с удовлетворительной для меня скоростью (видимо, в первый раз невнимательно провел эксперимент).
Так что большое спасибо тов. Disappear и всем кто откликнулся.