Перефразируя:
У меня есть таблица с 500K строк. Специальный запрос без хорошего индекса для его поддержки требует полного сканирования таблицы. Я хотел бы сразу просмотреть первые возвращенные строки, пока продолжается полное сканирование таблицы. Затем я хочу просмотреть следующие результаты.
Кажется, что вам нужна какая-то система, в которой могут работать два (или более) потока. Один поток будет занят синхронным извлечением данных из базы данных и сообщением о ходе выполнения остальной части программы. Другой поток будет иметь дело с дисплеем.
А пока я хотел бы отобразить ход сканирования таблицы, например: "Поиск ... найдено 23 из 500 000 строк на данный момент".
Не ясно, что ваш запрос вернет 500 000 строк (на самом деле, будем надеяться, что это не так), хотя, возможно, ему придется просканировать все 500 000 строк (и вполне может найти только 23 строки, которые пока соответствуют). Определить количество строк, которые должны быть возвращены, сложно; определить количество строк для сканирования проще; определить количество уже отсканированных строк очень сложно.
Если я прокручиваю слишком далеко вперед, я хочу отобразить сообщение вроде: «Достигнута последняя строка в буфере предварительного просмотра ... запрос еще не завершен».
Итак, пользователь прокрутил 23-ю строку, но запрос еще не завершен.
Можно ли это сделать? Может быть как: spawn / exec, объявить курсор прокрутки, открыть, получить и т. Д .?
Здесь есть пара вопросов. СУБД (верно для большинства баз данных и, конечно, для IDS) остается привязанной к текущему соединению при обработке одного оператора. Получить обратную связь о том, как продвигался запрос, сложно. Можно посмотреть оценочные строки, возвращаемые при запуске запроса (информация в структуре SQLCA), но эти значения могут быть неверными. Вам нужно будет решить, что делать, когда вы достигнете строки 200 из 23, или вы попадете только в строку 23 из 5697. Это лучше, чем ничего, но это не надежно. Определить, как далеко продвинулся запрос, очень сложно. И некоторые запросы требуют фактической операции сортировки, а это означает, что очень трудно предсказать, сколько времени это займет, потому что данные не доступны, пока не будет выполнена сортировка (а после того, как сортировка завершена, для связи между СУБД и приложение для задержки доставки данных).
Informix 4GL имеет много достоинств, но поддержка потоков не является одним из них. Язык не был разработан с учетом безопасности нитей, и нет простого способа установить его в продукт.
Я думаю, что то, что вы ищете, будет легче всего поддерживать в двух потоках. В однопоточной программе, такой как программа I4GL, нет простого способа выключить и извлечь строки, ожидая, пока пользователь введет еще какой-нибудь ввод (например, «прокрутить следующую страницу, полную данных»).
Оптимизация FIRST ROWS является подсказкой для СУБД; это может или не может дать значительную выгоду воспринимаемой производительности. В целом, это обычно означает, что запрос обрабатывается менее оптимально с точки зрения СУБД, но быстрое получение результатов для пользователя может быть более важным, чем рабочая нагрузка на СУБД.
Где-то внизу, в ответе с большим количеством голосов, Фрэнк кричал (но, пожалуйста, не кричите):
Это именно то, что я хочу сделать, запустить новый процесс, чтобы начать отображать first_rows и прокручивать их, даже если запрос еще не завершен.
OK. Трудность здесь заключается в организации IPC между двумя процессами на стороне клиента. Если оба подключены к СУБД, они имеют отдельные подключения, и поэтому временные таблицы и курсоры одного сеанса недоступны для другого.
Когда выполняется запрос, создается временная таблица для хранения результатов запроса для текущего списка. Устанавливает ли механизм IDS эксклюзивную блокировку для этой временной таблицы до завершения запроса?
Не все запросы приводят к временной таблице, хотя набор результатов для курсора прокрутки обычно имеет что-то примерно эквивалентное временной таблице. IDS не нужно устанавливать блокировку для временной таблицы, поддерживающей курсор прокрутки, потому что только IDS может получить доступ к таблице. Если бы это была обычная временная таблица, по-прежнему не было бы необходимости блокировать ее, потому что к ней нельзя получить доступ, кроме как через сеанс, который ее создал.
Что я имел в виду под строками 500k, так это nrows в запрашиваемой таблице, а не сколько ожидаемых результатов будет возвращено.
Возможно, более точное сообщение о состоянии было бы:
Searching 500,000 rows...found 23 matching rows so far
Я понимаю, что точное количество nrows можно получить в sysmaster: sysactptnhdr.nrows?
Возможно; Вы также можете получить быстрый и точный подсчет с помощью «SELECT COUNT (*) FROM TheTable»; это ничего не сканирует, а просто обращается к управляющим данным - вероятно, фактически к тем же данным, что и в столбце nrows таблицы SMI sysmaster: sysactptnhdr.
Таким образом, порождение нового процесса не является очевидным рецептом успеха; Вы должны перенести результаты запроса из порожденного процесса в исходный процесс. Как я уже говорил, многопоточное решение с отдельными потоками отображения и доступа к базе данных будет работать по-своему, но есть проблемы с выполнением этого с использованием I4GL, поскольку оно не поддерживает потоки. Вам все равно придется решить, каким образом код на стороне клиента будет хранить информацию для отображения.