:: Visual Foxpro, Foxpro for DOS
ошибка при индексировании большого файла
igoza

Сообщений: 127
Дата регистрации: 05.09.2007
Добрый день! Скачал ФМС-овский файл для проверки паспортов, сделал из него dbf, > 108 000 000 записей, хотел проиндексировать по серии и номеру паспорта,
индекс по полю С(4) строится, а по полу С(6) нет - ошибка С00000094. Что это, ограничение Фокса или
моего компа (VFP9+SP2, Windows7) или еще что-то ?
Ratings: 0 negative/0 positive
Re: ошибка при индексировании большого файла
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Может большой файл (1Г), вот и не индексирует. Может, если посчитать размер индекса, он будет больше самого файла.

Я с этим файлом недействительных паспортов ФМС поступил по другому:
Структура таблички (серия C(4), номера M), где
серия - это просто серия паспорта C(4)
номера - это битовое поле 10^6 бит = ок. 100кБайт. Если бит N (1..999999) установлен, значит этот номер паспорта присутствует в файле ФМС для заданной значения в поле "серия".

В результате сама табличка DBF оказалась малого размера (< 10^4 * 10 = 0.1МБайт), можно и не индексировать по серии, не важно. А поиск № паспорта выливается в поиск в поле Memo № байта (INT(номер/8)), и номера бита в нем (номер%8), и далее BITTEST(...). Индекс не понадобился, и файл FPT оказался ок. 0.3Г. Муторнее оказалось изготовление этого файла - фоксовыми операторами заняло до 1 сут. Сделал на операциях в памяти SYS(2600), теперь за неск. часов изготовляется...
Ratings: 0 negative/0 positive
Re: ошибка при индексировании большого файла
igoza

Сообщений: 127
Дата регистрации: 05.09.2007
Спасибо, подход интересный. Догадка относительно величины, наверное, правильная: разделил файл на 2, половинки индексируются без проблем.
Ratings: 0 negative/0 positive
Re: ошибка при индексировании большого файла
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
of63
Я с этим файлом недействительных паспортов ФМС поступил по другому:
habrahabr.ru


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: ошибка при индексировании большого файла
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
На ноуте с ssd:
Create Cursor ListExpPassp (ser i, num i)
Append From list_of_expired_passports.csv type csv && пара минут
Index on num tag num && примерно столько же
Locate for num = 904008 and ser = 8308 && меньше минуты
Select * from ListExpPassp where num = 904008 and ser = 8308 && мгновенно


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: ошибка при индексировании большого файла
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Ну да, список номеров (1..N) можно хранить и в виде битового поля на N бит, и как список номеров, каждый номер потребует LOG2(N) байт, (или еще как-то, но сравним эти два способа). Если в серии паспорта задействованы немного значений (например 100 при при N=10^6), то конечно выгоднее хранить все номера серии как список чисел, а если заполнение серии номерами "наполовину" - то как битовое поле, (и если заполнение "под завязку", то опять как список, но список незанятых номеров). Но, времени как всегда не было, и в Memo сохранил в любом случае как битовое поле, хотя можно было поставить признак типа хранения, и на этом еще сэкономить сотню-другую Мбайт... (Кстати, зипуются эти 0.3Г в 30МБайт, в 10 раз то есть, значит есть куда стремиться )

Доб. к примеру, что "все мгновенно". У меня что-то не пошло, и размер в 1Г не понравился, и я стал ужимать. Да, и поиск "меньше минуты" - это уже никуда не годится для ввода паспорта оператором. Из-за этой проверки ждать полминуты неразумно. Здесь как раз д.б. мгновенно. Select почему выполняется мгновенно - непонятно, может индексный файл закешировался в ОЗУ... Какого размера получился файл CDX?



Исправлено 3 раз(а). Последнее : of63, 13.07.17 17:16
Ratings: 0 negative/0 positive
Re: ошибка при индексировании большого файла
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
Делаем индекс
index on Right(Bintoc(num, '4s'), 3)+Bintoc(ser, '2s') tag num_ser
Потом пользуемся
?Indexseek(Right(Bintoc(num, '4s'), 3)+Bintoc(ser, '2s'), .f., 'Какой_там_у_тебя_алиас', 'num_ser')
и наслаждаемся "мгновенной" проверкой.


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: ошибка при индексировании большого файла
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Ну и хорошо, что мало кода, и мгновенно проверяет, но и у меня тоже худо-бедно, но тоже мгновенно ) ...но что-то мне нравится и в моем подходе. Это, наверное, странно, да? )
Ratings: 0 negative/0 positive
Re: ошибка при индексировании большого файла
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
"А кто ж не странен?" (C) (Потрясающий копьем). [sm128]
Ratings: 0 negative/0 positive
Re: ошибка при индексировании большого файла
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Сергей, посмотрел про этот "простой" код, чем же он не нравился, и вот результат:

- идея простая и правильная - создать индекс с длиной значения выражения покороче, идея работает
- но размер индексного файла (CDX) оказался = 0.5Г, а именно половина от исходного файла (DBF, 1Г, который тоже надо хранить, хотя и напрасно)
- мое решение занимает 0.3Г, (без тенденции роста с ростом исходного файла CSV), также
гарантировано будет работать "быстро" и в сетевой среде (для поиска номера требуется одно чтение Мемо-поля размером 100кБайт). В то время как поиск записи в CDX размером 0.5Г - не ясно во что выльется, но не измерял в сети...
- 1Г файла DBF в решении с полным CDX вобще не нужно, ведь достаточно найти наличие записи в CDX, а само чтение DBF не нужно, но в среде Fox DBF должен быть...

Вот "проверятельный" опус:
Ratings: 0 negative/0 positive
Re: ошибка при индексировании большого файла
Igor Korolyov
Автор

Сообщений: 34580
Дата регистрации: 28.05.2002
[quote of63]В то время как поиск записи в CDX размером 0.5Г - не ясно во что выльется, но не измерял в сети...
В чтение примерно 1.5-2Кб из cdx (правда за 3-4 отдельных операции по 512байт каждая, и потенциально из очень разных частей файла) и 25-30 байт из dbf (предполагая что dbf уже открыт на момент начала замера, иначе добавится ещё чтение 2-3Кб из индекса - описания его тегов, и 1 кб из dbf - заголовок и 1-я запись).
Теоретически можно вообще полностью свою бинарную структуру a-la фоксовый cdx сделать, и ограничится "только чтением индекса" (а главное хранением на диске лишь его).
IMHO всё же 100кб на "единое" битовое поле это перебор. Я не знаю какова статистическая структура этой информации, но чисто "для эксперимента" я бы сделал помимо "4 символа = серия + 125кб битовое поле для 6-значного номера", и варианты "5 символов = серия и 1 старший разряд номера + 12кб битового поля для оставшихся 5 знаков" возможно, даже и "6/4" вериант, с 1.2Кб битовым полем... Индекс, да и сам dbf в этом случае будет небольшой - fpt, конечно, такой же, если статистически "невалидные номера" распределены более-менее равномерно (т.е. нет ни "чистых" серий, ни "абсолютно скомпрометированных" - для них битовые поля не нужны, а нужен простой флажок что там ВСЕ "нули" или ВСЕ "единицы").


------------------
WBR, Igor
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 19 (Гостей: 19)

© 2000-2024 Fox Club 
Яндекс.Метрика