On-line: гостей 2. Всего: 2 [подробнее..]
АвторСообщение
постоянный участник




Пост N: 6370
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 28.07.19 23:38. Заголовок: REINDEX ...


Всем привет !
Не пользовался этой командой вообще. Делал закрытие индексов и создание нового индекса.
А как сделать REINDEX на драйвере CDX без закрытия индексов ?
Для простоты я использую один файл - один индекс.
Так привык давно делать, да и удобнее по Dbsetorder() переключаться.

Делаю так:
      SET AUTOPEN ON 
USE ( cDbf ) ALIAS TEST SHARED NEW // подключается автоматом test6.cdx
OrdSetFocus('ALL')
Dbsetorder(1)
....
// cUser := "1-user", "2-user" и т.д.
cIndx := GetStartUpFolder() + "\test6." + cUser + '.cdx'
DELETEFILE(cIndx) // обязательно
SELECT TEST
INDEX ON RECNO() TAG CODE1 TO (cIndx) FOR &cFilter ADDITIVE // условный индекс
OrdSetFocus('CODE1')
Dbsetorder(2)
GO TOP
...

Пытаюсь потом в программе сделать:
      SELECT(oBrw:cAlias) 
nOrder := INDEXORD()
IF nOrder == 2
// перестроить индекс
REINDEX // строка 897
ENDIF

Вылетает с ошибкой:
Error DBFCDX/1023 Exclusive required: W:\HB_Project\Tsb_Basic\Demo6\test6.dbf
--------------------------------- Stack Trace ---------------------------------
Called from ORDLISTREBUILD(0)
Called from RECNOREFRESH(897) in module: demo6.prg
Called from CHANGEWINBROWSE(1037) in module: demo6.prg
Called from (b)MAIN(47) in module: demo6.prg


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 26 , стр: 1 2 All [только новые]


постоянный участник


Пост N: 1543
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 29.07.19 08:17. Заголовок: REINDEX Rebuild ope..


REINDEX
Rebuild open indexes in the current work area
------------------------------------------------------------------------------
Syntax

REINDEX
[EVAL <lCondition>]
[EVERY <nRecords>]

Arguments

EVAL <lCondition> specifies a condition that is evaluated either for
each record processed or at the interval specified by the EVERY clause.
This clause is identical to the EVAL clause of the INDEX command, but
must be respecified in order for the reindexing operation to be
monitored since the value of <lCondition> is transient.

EVERY <nRecords> specifies a numeric expression that modifies how
often EVAL is evaluated. When using EVAL, the EVERY option offers a
performance enhancement by evaluating the condition for every nth record
instead of evaluating each record reindexed. The EVERY keyword is
ignored if no EVAL condition is specified.

Description

REINDEX is a database command that rebuilds all open indexes in the
current work area. When the reindexing operation finishes, all rebuilt
indexes remain open, order is reset to one, and the record pointer is
positioned to the first record in the controlling index. If any of the
indexes were created with SET UNIQUE ON, REINDEX adds only unique keys
to the index. If any of the indexes were created using a FOR condition,
only those key values from records matching the condition are added to
the index.

In a network environment, REINDEX requires EXCLUSIVE USE of the current
database file.
Refer to the "Network Programming" chapter in the
Programming and Utilities Guide for more information.

Caution! REINDEX does not recreate the header of the index file
when it recreates the index. Because of this, REINDEX does not help if
there is corruption of the file header. To guarantee a valid index,
always use INDEX ON in place of REINDEX to rebuild damaged indexes

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 7080
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 29.07.19 09:42. Заголовок: Andrey пишет: OrdSe..


Andrey пишет:

 цитата:
OrdSetFocus('CODE1')
Dbsetorder(2)


А на хрена ?
Коли юзаешь составной индекс , то крайне "криво" юзать
Dbsetorder , так как не известно каким по счету будет нужен тэг ,
юзай OrdSetFocus , этого достаточно. Об этом писал еще А. Кресин.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 6371
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 29.07.19 16:18. Заголовок: Если открываю базу в..


Если открываю базу в SHARED то условный индекс всё равно могу делать в отдельном месте для каждого юзера.
Мне нужно его пере индексировать.
Т.е. команда REINDEX не катит.
Тогда пойдём сложным путем, запоминаем открытые индексы, закрываем все индексы, восстанавливаем индексы, кроме нужного и делаем заново условную индексацию.
Спасибо за разъяснения !

Dima пишет:

 цитата:
Dbsetorder , так как не известно каким по счету будет нужен тэг ,
юзай OrdSetFocus , этого достаточно.


Для справки в программе у меня есть отдельный показ открытых баз и всех индексов с любого окна.
Мне просто надо посмотреть и всё видно - какой нужен номер Dbsetorder.
Да я привык уже к этому. Переделывать много чего надо.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3850
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 31.07.19 14:51. Заголовок: dbSetOrder и так реа..


dbSetOrder и так реализован через ordSetFocus. Первый из них принимает только числовой параметр индекса, а второй - и числовой, и символьный, т.е. имя тэга.

Запись вида

OrdSetFocus('ALL')
Dbsetorder(1)

эквивалентна

OrdSetFocus('ALL')
OrdSetFocus(1)

Если All - первый тэг, то здесь два раза выполняется одна и та же операция.

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

Что касается индекса по условию, то, насколько я понял, индекс каждый раз перестраивается для другого условия. Не сказал бы, что это красивое решение, но сейчас не об этом. По факту это временный индекс - его построили, использовали и выбросили. Поэтому нецелесообразно держать его в общем составном индексе, лучше его формировать в отдельном индексном файле. Временный он и есть временный.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 6375
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 31.07.19 17:09. Заголовок: Pasha пишет: Что ка..


Pasha пишет:

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


А другого решения нет. Юзер как хочет, любые списки получает и делает с ними что угодно, хоть печатает, или изменяет данный список.
Сколько полей в БД находиться (или спец.список полей) по стольким и выборку (условную индексацию) юзер делает
и ко мне не пристаёт !!!

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 364
Зарегистрирован: 29.05.10
ссылка на сообщение  Отправлено: 01.08.19 09:39. Заголовок: Andrey пишет: А дру..


Andrey пишет:

 цитата:
А другого решения нет.



Ну что Вы, Андрей . Вы точно знаете, что есть и другие решения. Просто забыли....
Вот же Вам только что написали -

Pasha пишет:

 цитата:
По факту это временный индекс - его построили, использовали и выбросили. Поэтому нецелесообразно держать его в общем составном индексе, лучше его формировать в отдельном индексном файле. Временный он и есть временный.



Если на основной базе будет хотя бы один один индекс этого достаточно.
И любой пользователь будет иметь свой индексный файл на своей локальной машине построенный на основе основного. Никому не мешать и не "дергать" основную базу. Ну Вы же помните, приблизительно вот так -
index on &mykey to tsmy_idx for !deleted() CUSTOM ADDITIVE
Т.е. -
Andrey пишет:

 цитата:
как хочет, любые списки получает и делает с ними что угодно



Кстати очень удобно и наглядно для этого использовать бровс.
Мне кажется этот вопрос уже обсуждался ...

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 6377
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 01.08.19 13:44. Заголовок: ММК пишет: Если на ..


ММК пишет:

 цитата:
Если на основной базе будет хотя бы один один индекс этого достаточно.
И любой пользователь будет иметь свой индексный файл на своей локальной машине построенный на основе основного. Никому не мешать и не "дергать" основную базу. Ну Вы же помните, приблизительно вот так -
index on &mykey to tsmy_idx for !deleted() CUSTOM ADDITIVE



Так я и делаю. На основной базе несколько индексов, и по ним строю условный индекс.
cFilter := "RCity==1.AND.Kstreet=50 .AND ...... !deleted()" 
index on &mykey to tsmy_idx for &cFilter CUSTOM ADDITIVE


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 6411
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 02.09.19 16:25. Заголовок: Вопрос возник другой..


Вопрос возник другой по базе.
Нужно по условному индексу создать массив с номерами записи.
На маленьких базах это происходит быстро.
Если базы большие, 30 тыч.записей и больше, то тормоза...
Можно ли как то ускорить этот процесс ?
Сделать несколько потоков что ли или ещё как то по другому ?
Вот код который у меня сейчас:
 
aRecno := {}
aBeg := WaitWinCreateModal( 'Считываю текущий список...' )
nPokaz := INT( nRecnoAll / 100 ) // показ каждые 1%
FOR nI := 1 TO nRecnoAll
ORDKEYGOTO(nI)
AADD( aRecno, RECNO() )
IF nI % nPokaz == 0 // выводим через XXX записей
cMsg := HB_NtoS(nI)+"/"+HB_NtoS(nRecnoAll)
WaitWinTimer(aBeg, cMsg) // показ окна ожидания
ProcessMessages() // ОБЯЗАТЕЛЬНО ! Чтобы форма НЕ замирала
ENDIF
NEXT
WaitWinClose(aBeg) // убить окно ожидания


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3871
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 02.09.19 19:37. Заголовок: вместо FOR nI := 1 T..


вместо
FOR nI := 1 TO nRecnoAll
ORDKEYGOTO(nI)
..
NEXT

используй

go top
while ! eof()
...
skip
enddo

или еще проще:

dbeval({|| ...})

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 6412
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 02.09.19 20:47. Заголовок: Pasha пишет: исполь..


Pasha пишет:

 цитата:
используй ....


А мне нужно по условному индексу создать массив с номерами записи.

Я помню что dbeval({|| ...}) быстрей работает.
А как его прикрутить к условному индексу ?

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3872
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 02.09.19 21:02. Заголовок: Andrey пишет: как ..


Andrey пишет:

 цитата:
как его прикрутить к условному индексу ?



Странный вопрос. Надо сделать этот индекс активным. Индекс ведь для этого и нужен

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2790
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 02.09.19 21:08. Заголовок: Andrey пишет Я помню..


Andrey пишет
 цитата:
Я помню что dbeval({|| ...}) быстрей работает


Быстрее работает цикл, блок кода отстает ~2-5 сек. на больших базах

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 6413
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 02.09.19 21:47. Заголовок: Pasha пишет: Странн..


Pasha пишет:

 цитата:
Странный вопрос. Надо сделать этот индекс активным. Индекс ведь для этого и нужен


Так я и об этом пишу, и код привел по условному индексу обход базы.
Забыл указать
nRecnoAll := ORDKEYCOUNT()
а далее
 
FOR nI := 1 TO nRecnoAll
ORDKEYGOTO(nI)
AADD( aRecno, RECNO() )
.....

Даже если сразу объявить массив
         aRecno := Array(nRecnoAll)   // создаём массив  
FOR nI := 1 TO nRecnoAll
ORDKEYGOTO(nI)
aRecno[nI] := RECNO()
......

то на малых базах - до 20 тыс. считывается RECNO() где-то 10 минут, а на больших 35-55 тыс. уже по 60 минут и более.
Почему так ? Как можно ускорить ?

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2792
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 02.09.19 21:57. Заголовок: Andrey Pasha прямо ..


Andrey
Pasha прямо пишет, делай
 
go top
while ! eof()
...
skip
enddo

Зачем по индексу OdrKeyGoto(nI) ? Индекс без тебя это сделает, т.е.
set order to 3
go top
do while ! eof()
add(aRec,recno())
skip
enddo

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 6414
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 02.09.19 22:09. Заголовок: SergKis пишет: Инде..


SergKis пишет:

 цитата:
Индекс без тебя это сделает, т.е.


Теперь понял ! Спасибо !

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3874
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 02.09.19 22:22. Заголовок: Andrey пишет: то на..


Andrey пишет:

 цитата:
то на малых базах - до 20 тыс. считывается RECNO() где-то 10 минут, а на больших 35-55 тыс. уже по 60 минут и более.
Почему так ? Как можно ускорить ?



Может быть стоит переделать алгоритм ? Зачем в цикле по таблице загонять все номера записей в массив ? Есть же индекс, он и так дает индексно-последовательный доступ к нужным данным
Считывать по часу данные - это жесть. Зачем в таком виде это нужно то ?

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 6415
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 02.09.19 22:35. Заголовок: Pasha пишет: Считыв..


Pasha пишет:

 цитата:
Считывать по часу данные - это жесть. Зачем в таком виде это нужно то ?


Вот и я о том же. Нужно переделать алгоритм.

Сделал как рекомендовал и я выпал в осадок.
Вот результат:
кол-во записей в БД: 52411
затрачено времени: 00:00:00.448

Блин, FOR / NEXT по базе совсем не то

Вот код (кому интересно)
Скрытый текст

Программа просто полетела в этой менюшке.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 6416
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 02.09.19 23:23. Заголовок: Сделал в другом меню..


Сделал в другом меню обработку БД, проще алгоритм, чтение и запись по текущей базе.
кол-во записей в БД:	59120	 
Было раньше затрачено времени: 00:01:20.102
Стало теперь 00:00:10.502


Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 224
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 05.09.19 13:42. Заголовок: Andrey пишет: кол-в..


Andrey пишет:

 цитата:
кол-во записей в БД: 59120
Было раньше затрачено времени: 00:01:20.102
Стало теперь 00:00:10.502



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

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3877
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 05.09.19 14:01. Заголовок: Эх, было время, когд..


Эх, было время, когда компьютеры были компьютеры, а не суперкомпьютеры, как сейчас. И если ты не оптимизируешь код - это сразу становилось заметно.
А сейчас хоть оптимизируй, хоть не оптимизируй - работает одинаково.
Разве что очень крутой косяк будет заметным.

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 26 , стр: 1 2 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 686
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет