RecordCount

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

joolio
Сообщения: 31
Зарегистрирован: 09 июл 2005, 14:23

RecordCount

Сообщение joolio » 04 авг 2005, 14:57

Здраствуйте!
Дело в том что Ibquery.recordcount показывает не полное количество записей, а зависит от DBGrid то есть если в DBGrid 16 строк а кол. записей 20 то все равно первоначально показывает 16. Меняется только тогда когда меняется курсор

NT Man
Сообщения: 17
Зарегистрирован: 24 янв 2005, 12:29

Re: RecordCount

Сообщение NT Man » 04 авг 2005, 15:11

joolio писал(а):Здраствуйте!
Дело в том что Ibquery.recordcount показывает не полное количество записей, а зависит от DBGrid то есть если в DBGrid 16 строк а кол. записей 20 то все равно первоначально показывает 16. Меняется только тогда когда меняется курсор
после:
ibquery.Open;
поставь:
ibquery.FetchAll;

HeadHunter
Сообщения: 19
Зарегистрирован: 30 ноя 2005, 17:48

Сообщение HeadHunter » 14 дек 2005, 18:54

IBQuery->FetchAll() длится очень долго (30 секунд)
Иных путей, так понимаю, нет?
А как сделать чтобы пользователь не пугался?
Какую-нибудь интерактивность IBQuety предоставляет?
Или пошел запрос - и всё, кури, приятель, а приложение "повисит", пока запрос не выполнится?

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 14 дек 2005, 19:19

HeadHunter писал(а):IBQuery->FetchAll() длится очень долго (30 секунд)
Это как повезёт. Может мухой отлететь, а может и минут 10 телепаться. Смотря какой длины и ширины результат попадётся.
HeadHunter писал(а): Иных путей, так понимаю, нет?
Путей в куда?
HeadHunter писал(а): А как сделать чтобы пользователь не пугался?
Не пугать. Особенно на пустом месте. С целью нарисовать сбоку грида бантик с надписью "Поздравляю Вас! Вы поймали 10 000 000 записей!"
HeadHunter писал(а): Какую-нибудь интерактивность IBQuety предоставляет?
Это хто? в смысле "интерактивность" и в смысле "IBQuety"?
HeadHunter писал(а): Или пошел запрос - и всё, кури, приятель, а приложение "повисит", пока запрос не выполнится?
А как должно быть? Вот так:

Пошёл запрос. Получил первый пакет записей. Поучил указание - ТягайФсё. И

- Ой. Я запись нашёл!
- Ой. Христофор Бонифатьевич, ещё крокодильчик!
- Ой...

В принципе можно в одной нити FetchAll делать, а в другой порнушку юзеру показывать, чтоб не скучал...

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 14 дек 2005, 20:08

ага, только этот select count по замудренному запросу не выполнится, это раз, или может выполняться ооочень долго, это два.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 14 дек 2005, 20:10

alex-co писал(а):Возьмите FIBPlus и не мучайтесь, для получения правильного числа записей в IBx нужно прогрузить все записи в память или выполнить к таблице из которой идет выборка еще 1 запрос

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

select count(*) from Table
, который и вернет кол-во записей.
В FIBPlus все это уже реализовано и DataSet можно настроить так, что он будет показывать реальное кол-во записей.
А всё-тки. Если там взаправду 10 000 000 записей или сам запрос представляет собой многоэтажный и весьма неторопливый джойн - второй запрос с каунтом с тем же From и Where всё равно будет "не мучайтесь"? Особенно если учесть, что, например, в read_commited его результат запросто может не сойтись с тем, что мы реально дофетчим когда-нить, когда доберёмся до конца основного запроса. А если в основном запросе наличествуют агрегаты и группировки? Так что я бы всё-тки советовал не "не мучаться", а "не маяться". Фигнёй с количеством записей в выборке.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 14 дек 2005, 20:56

правильно. только обычно никто ничего не читает, и лепит, и лепит....
поэтому давать такие советы, как твой, надо очень осторожно. Например, сказать, что вот есть такая возможность, и обязательно (!) указать чем это чревато. Или вообще сказать "нет". А когда человек докопается, если ему надо, он уже будет в состоянии отличить хорошее от плохого.

Например, мы с "Рустамом" на sql.ru так и не договорились по этому поводу.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 14 дек 2005, 22:00

alex-co писал(а):Merlin, kdv, ну так я думаю голова нужна не только, что бы шляпу носить и люди в состоянии понять когда этот режим можно включать когда нет, если не в состоянии, то можно и хелпы почитать или "Мир InterBase", где описаны ограничения при использовании данного подхода
И в мыслях не было на тебя наезжать. Говорил для вопрошающего, ибо из того, что он не совсем понимает что есть recordcount и с чем его едят, явно следует что в хелп по TIBSQL он не заглядывал и о тонкостях не задумывался. Это у меня литературная манера такая.

HeadHunter
Сообщения: 19
Зарегистрирован: 30 ноя 2005, 17:48

Сообщение HeadHunter » 15 дек 2005, 13:46

Это как повезёт. Может мухой отлететь, а может и минут 10 телепаться. Смотря какой длины и ширины результат попадётся.
что нужно для минимизации времени работы FetchAll()?
при условии одинакового кол-ва записей?
запрос простейший - SELECT * из одной таблицы по старту программы
далее, все записи из полученного набора данных преобразовываются и перекачиваются в память
соответственно, хотелось бы на сплэшскрин повесить прогрессбар, который будет весело предсказвать сколько осталось ждать.
Путей в куда?
Когда-то искал ответ на вопрос, может ли TQuery как-либо сигнализировать о своей работоспособности после вызова Open(), выполнение которого занимает длителное время. Наподобие раз в N секунд вызывать пользовательскую ф-цию, которая будет кричать "крокодилы еше не кончились, а я (Query) еще не вишу"
Не пугать. Особенно на пустом месте. С целью нарисовать сбоку грида бантик с надписью "Поздравляю Вас! Вы поймали 10 000 000 записей!"
пользователь, он нервный... особенно после предыдущей версии программы, в которой нет никаких задержек на НЕОПРЕДЕЛЕННОЕ время... начнет три кнопки давить... а писать "Ждите и будет счастье" - не хотелось бы.
Это хто? в смысле "интерактивность" и в смысле "IBQuety"?
"интерактивность" см "путей в куда"
IBQuery
А как должно быть? Вот так:

Пошёл запрос. Получил первый пакет записей. Поучил указание - ТягайФсё. И

- Ой. Я запись нашёл!
- Ой. Христофор Бонифатьевич, ещё крокодильчик!
- Ой...
спасибо, количество крокодилов всё так же заранее неизвестно
В принципе можно в одной нити FetchAll делать, а в другой порнушку юзеру показывать, чтоб не скучал...
можно, да, гораздо проще чем с крокодилами, а пользы столько же

HeadHunter
Сообщения: 19
Зарегистрирован: 30 ноя 2005, 17:48

Сообщение HeadHunter » 15 дек 2005, 14:00

Merlin писал(а): Говорил для вопрошающего, ибо из того, что он не совсем понимает что есть recordcount и с чем его едят, явно следует что в хелп по TIBSQL он не заглядывал и о тонкостях не задумывался.
Заглядывал. Не задумывался. Из того, что я понял, следует, что RecordCount обновляется по мере перемещения по сформированному набору данных. Например, если после Open() сделать Last(), RecordCount станет тем что мне нужно, но выполнение Last() соизмеримо с FetchAll().

Скажите, можно ли при помощи команд SQL вернуть кол-во всех записей в одной таблице?
Данные инструкции предназначены для этого?
select count(*) from Table
Возникла мысль создать в базе служебную таблицу, где хранить размеры рабочих таблиц (кол-во записей в них).
Модификация рабочих таблиц будет происходить редко, тогда же и перезаписывать содержимое этих служебных таблиц. Зато при старте программы быстренько вычитал из служебной таблицы кол-ва записей в рабочих таблицах - и всё в ажуре...

Или это изврат?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 15 дек 2005, 14:18

Скажите, можно ли при помощи команд SQL вернуть кол-во всех записей в одной таблице?
никак, тебе уже объяснили. см. выше. например в read_committed при многопользовательской работе мало того что select count в разные моменты времени будет выдавать разные данные, так еще и без fetch all
нельзя точно сказать, сколько выберет запрос, получающий данные с сервера кусками.

например, начали выборку. параллельно другой пользователь добавил 100 записей, из которых 50 попадает под условие выборки. сделал commit. Теперь мы продолжаем выбирать остальные записи, и о - получаем новые 50.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 15 дек 2005, 14:56

HeadHunter писал(а): Скажите, можно ли при помощи команд SQL вернуть кол-во всех записей в одной таблице?
Савва! Ну скажи ты мне! Ну зачем тебе это нужно?!!! (C). Информация бессмыссленная, бесполезная, неточная. Голое украшательство экранной формы.

- Доктор, если я делаю вот так, то мне больно.
- Ну так не делайте вот так.

Или терпите.

HeadHunter
Сообщения: 19
Зарегистрирован: 30 ноя 2005, 17:48

Сообщение HeadHunter » 15 дек 2005, 17:48

А если упростить условия.
БД однопользовательская, модификаций не происходит.
С этими допущениями информация будет точной.

Просто интересно, там, глубоко, в недрах СУБД, неужели для такого объекта как таблица, не ведётся счетчик записей?

Merlin, я считаю это не голым украшательством, а улучшением пользовательского интерфейса программы... Вам нравится, к примеру, скачивать файлы, где менеджер закачки показывает размер "N/A"? Мне-не очень...

Да ладно, я уже всё таки вспомогательную таблицу ввёл... :roll:
Работает, замечательно...

До кучи вопрос (да-да сам могу выяснить, но проще спросить) - когда буду делать удаление записей в таблице, это как-нибудь скажется на размере файла БД? Записи наверное будут, наподобие как в парадоксе, помечаться удалёнными?

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 15 дек 2005, 18:10

HeadHunter писал(а): Просто интересно, там, глубоко, в недрах СУБД, неужели для такого объекта как таблица, не ведётся счетчик записей?
Нет, не ведётся. Потому что в общем случае на MGA архитектуре это невозможно. А делать отдельный движок и On Disk Structure для read only databases никто не будет. Хотя... это же Open Source, скачивай и займись ;)
HeadHunter писал(а): Merlin, я считаю это не голым украшательством, а улучшением пользовательского интерфейса программы... Вам нравится, к примеру, скачивать файлы, где менеджер закачки показывает размер "N/A"? Мне-не очень...
Ты знаешь, мои задачи на базе СУБД не занимаются скачиванием файлов. И не показывают порнушку. И музычку не играют. Если в любой OLTP подсистеме запрос с нормально сформулированными пользователем условиями работает больше 20 сек, то кодер получает по зопе. OLAP - отдельная песня, но эта категория пользователей понимает чего стоят их запросы и готовы подождать. Обычно тоже не особо долго, потому что полуфабрикатные агрегаты под их типовые запросы собираются по ночам в спициятельные таблички. А сколько записей попало в обычный запрос - это последнее что может интересовать любую категорию пользователей.
HeadHunter писал(а): Да ладно, я уже всё таки вспомогательную таблицу ввёл... :roll:
Работает, замечательно...
Ну и ладушки. Не забудь теперь создать табличку для хранения количеств записей в каждом запросе типа

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

 Select SRQ.CnPrice, SRQ.OutPrice, SCP.Skidka,
     SCP.Nomer, SCL.RateVSc, SCL.DateSc,
     SRQ.Store, SRQ.Code, ORT.RealDate,
     SL.Code, WSC.ZakPrvCode, SL.PriceDDU, SL.OrdRate,
     COC.CodContr, COC.SUSL, COC.Code, OTC.Sname, SCS.PriceSK, SL.PriceVC,
     ZPR.NomZak, SCL.NomDoc, ZPR.DateOrd, CNT.Contr_Type
   From WIMP_SC WSC, SORQS_Prices SRQ, Otgr_Req_Traect ORT,
        ZakPrv ZPR, OK_Link OKL, SostLetters SL, Contracts CNT,
        SC_Post SCP, SC_Lst SCL,
        SCP_Cond SCC, Contr_OC COC, Otgr_Cond OTC, SCP_Sost SCS
   Where WSC.KodTov=:KodTov And WSC.ScTip=:TipSc And WSC.ScStore=:StoreContr
     And ORT.Store=WSC.TPStore And ORT.Code=WSC.TPCode
     And ORT.Nomer=1 And ORT.RealDate Is Not NULL
     And SRQ.Store=ORT.Store And SRQ.Code=ORT.Code And SRQ.Point=ORT.Point
     And SRQ.KodTov=WSC.KodTov And SRQ.KolInt>0 And SRQ.CnPrice>1e-06
     And ZPR.StoreContr=WSC.StoreContr And ZPR.Code=WSC.ZakPrvCode
     And OKL.StoreContr=ZPR.StoreContr And OKL.ZakPrvCode=ZPR.Code
     And SL.StoreContr=OKL.StoreContr And SL.Code=OKL.SostCode
     And SL.KodTov=WSC.KodTov
     And CNT.StoreContr=SL.StoreContr And CNT.CodContr=SL.CodContr
     And SCP.Tip=WSC.ScTip And SCP.Store=WSC.ScStore
     And SCP.Nomer=WSC.ScNomer
     And SCL.Tip=SCP.Tip And SCL.Store=SCP.Store
     And SCL.Nomer=SCP.Nomer
     And SCC.TipSc=SCL.Tip And SCC.StoreSc=SCL.Store
     And SCC.NomerSc=SCL.Nomer
     And COC.StoreContr=SCC.StoreContr And COC.Code=SCC.CodeOc
     And OTC.Code=COC.Condition
     And SCS.Tip=WSC.ScTip And SCS.Store=WSC.ScStore
     And SCS.Nomer=WSC.ScNomer And SCS.ZakPrvCode=WSC.ZakPrvCode
     And SCS.KodTov=WSC.KodTov
Для начала на всём поле определения двух фигурирующих в нём параметров. А потом подумаем про наложение дополнительных условий фильтрации на таблички и хранения количеств записей, попоадающих в запрос при их применении :-D :-D :-D
HeadHunter писал(а): До кучи вопрос (да-да сам могу выяснить, но проще спросить) - когда буду делать удаление записей в таблице, это как-нибудь скажется на размере файла БД? Записи наверное будут, наподобие как в парадоксе, помечаться удалёнными?
Иди читай доки. 1. Не скажется. 2. Наверное. Наподобие.

HeadHunter
Сообщения: 19
Зарегистрирован: 30 ноя 2005, 17:48

Сообщение HeadHunter » 15 дек 2005, 18:36

Нет, не ведётся. Потому что в общем случае на MGA архитектуре это невозможно. А делать отдельный движок и On Disk Structure для read only databases никто не будет. Хотя... это же Open Source, скачивай и займись ;)
Спасибо.
Нет ни желания, ни времени.
В свободное время почитаю что такое MGA архитектура и почему это невозможно.
Ты знаешь, мои задачи на базе СУБД не занимаются скачиванием файлов. И не показывают порнушку. И музычку не играют. Если в любой OLTP подсистеме запрос с нормально сформулированными пользователем условиями работает больше 20 сек, то кодер получает по зопе. OLAP - отдельная песня, но эта категория пользователей понимает чего стоят их запросы и готовы подождать. Обычно тоже не особо долго, потому что полуфабрикатные агрегаты под их типовые запросы собираются по ночам в спициятельные таблички. А сколько записей попало в обычный запрос - это последнее что может интересовать любую категорию пользователей.
Круто, да.
Я просто поинтересовался, что удобнее, на Ваш взгляд, пользователю: знать, сколько продлится вычислительная операция, или не знать. Абстрагируясь от СУБД, порнушки и 20 сек запросов.
А Вы про какие-то проекты, полуфабрикаты, агрегаты...
Ну и ладушки. Не забудь теперь создать табличку для хранения количеств записей в каждом запросе типа
...
В контексте моей задачи подобное будет лишним.
Иди читай доки. 1. Не скажется. 2. Наверное. Наподобие.
Если никто не ответит - почитаю, естественно...

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 15 дек 2005, 19:00

HeadHunter писал(а): В свободное время почитаю что такое MGA архитектура и почему это невозможно.
О! Процесс пошёл :)
Я просто поинтересовался, что удобнее, на Ваш взгляд, пользователю: знать, сколько продлится вычислительная операция, или не знать. Абстрагируясь от СУБД, порнушки и 20 сек запросов.
А Вы про какие-то проекты, полуфабрикаты, агрегаты...
Я про реальный мир. А не про философические рассуждения общего плана. Что есть вычислительная операция? Интервал времени между передачей запроса серверу и началом поступления на клиент данных? Для простого запроса он не зависит от объёма выборки. Вообще. Он зависит от объёма ресурсов, потребных для оптимизатора при подготовке к выдаче данных на клиента и от объёма работы, которую он при этом должен выполнить. Для запроса с сортировкой или группировкой - зависит. Причём если сортировка по индексу - то тоже почти не зависит. Группировка по индексу - зависит не от объёма выборки, а от количества дубликатов в этом индексе. Или вычислительная операция - полный фетч? Абсолютно непредсказуемо. Зависит опять же от запроса, от качества индексов и постренного на них плана, от степени засранности данных мусором. Наконец, от клентского менеджера памяти, который озабочен выделением её под поступающий поток данных.
Иди читай доки. 1. Не скажется. 2. Наверное. Наподобие.
Если никто не ответит - почитаю, естественно...
Во-первых, я уже ответил. Во-вторых, действительно пора.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 15 дек 2005, 21:00

ради такого дела процитирую себя, из неопубликованного. я это иногда на курсах показываю, как вопрос. 80% людей впадают в ступор, почему то...

"В многопользователських системах невозможно сразу определить, какие записи видны конкретной транзакции, а какие нет. Это зависит от уровня изоляции транзакции. Для того, чтобы понять, что не все так просто, имеет смысл совершить микро-экскурс в область версионности. Предположим что с данными работают одновременно 3 клиента, которые стартуют и завершают транзакции соответственно:

в таблице TABLE 100 записей
- началась транзакция 1 в режиме read committed
- началась транзакция 2
- транзакция 2 удалила 5 записей
- началась транзакция 3 в режиме repeatable read (snapsot)
- транзакция 1 вставила 4 записи

вопрос - сколько выдаст select count для каждой из трех транзакций?

ответ: первая - 104, вторая - 95, третья - 100.

теперь предположим, что транзакция 2 сделала commit (завершилась), и повторим вопрос:

ответ: первая - 99 (95+4), третья - 100.

причем если транзакция 1 завершится rollback, то новая транзакция при count увидит 95 записей, а третья будет продолжать видеть 100. При этом общее количество версий записей по завершению транзакции 2 (неважно, commit или rollback) составит 100 + 5 + 4 = 109.

примечание: если вы не поняли, почему результаты ответов правильные, то следует обратиться к статьям по версионности записей на ibase.ru.

Даже если предположить, что внутри сервера для каждой транзакции можно сделать счетчик записей (с учетом insert и delete внутри этой транзакции), все равно невозможно предсказать результат select count(*) после commit или rollback конкурирующих транзакций. Именно поэтому для подобных запросов возможно узнать результат только при помощи перебора записей на диске."

Ответить