Существует таблица формата:
Create Table TblValue_1(
f_value float
, i_col smallint
, i_row smallint
)
После заполнения таблицы делаю
Commit Table TblValue_1
Create Index On TblValue_1 (i_col)
Create Index On TblValue_1 (i_row)
Необходимо получить для каждой строки массив SomeArray() as float, состоящий элементов имеющих соседние значения i_col или i_row.
Код следующий:
Set Event Processing Off
for i = 1 to iMaxX
for j =1 to iMaxY
SELECT f_value "fValue" FROM TblValue_1WHERE (i_col >= (i - 1) AND i_col <= (i + 1) AND i_row >= (j- 1) AND i_row <= (j + 1)) INTO _tmp
SELECT Count(*) "iCountElement" FROM _tmp INTO _tmp2
Fetch First From _tmp2
iCountElements = _tmp2.iCountElement ' количество элементов
redim SomeArray(iCountElements)
Close Table _tmp2
Fetch First From _tmp
for i = 1 to iCountElements
SomeArray(i) = _tmp.fValue
Fetch Next From _tmp
next
Close Table _tmp
next
next
Set Event Processing On
При iMaxX = iMaxY = 5 выполнение кода подвисает на приличное время.
Как ускорить алгоритм? что делаю не так? Как проще получить количество строк в запросе?
Имеет ли смысл Set Event Processing Off...Set Event Processing On если к строкам таблицы будут привязаны объекты и таблица TblValue_1 будет показана слоем?
Медленный запрос - оптимизация
-
- Новоприбывший
- Сообщения: 13
- Зарегистрирован: 04 июл 2010, 19:53
- Репутация: 0
-
- Активный участник
- Сообщения: 120
- Зарегистрирован: 14 апр 2011, 13:24
- Репутация: 5
- Откуда: Екатеринбург
Re: Медленный запрос - оптимизация
вот это:2ndBr.Е.Ж.'n'E.B. писал(а):Как проще получить количество строк в запросе?
Код: Выделить всё
SELECT Count(*) "iCountElement" FROM _tmp INTO _tmp2
Fetch First From _tmp2
iCountElements = _tmp2.iCountElement ' количество элементов
Close Table _tmp2
Код: Выделить всё
iCountElements = Tableinfo(_tmp, TAB_INFO_NROWS)
в данном случае Set Event Processing Off/On вообще смысла не имеет, поскольку приведенный код никак не влияет на объекты, отображаемые на экране (есть ли гр. объекты у таблицыTblValue_1, или нет, показана она в окне карты или нет - не важно). Исключение м.б. только в том случае, если у вас (или у пользователя вышей программы) висит в работе 1, 2..... приложений, имеющих в свем составе SelChangedHandler, и призванных, по замыслу авторов, "удобно, логично, и красиво" расположить информацию в окне Mapinfo в соотвествии со сделанным выбором. Но, если, не пренебрегать в операторах Select... ключиком Noselect, то можно не обращать внимания.2ndBr.Е.Ж.'n'E.B. писал(а):Имеет ли смысл Set Event Processing Off...Set Event Processing On если к строкам таблицы будут привязаны объекты и таблица TblValue_1 будет показана слоем?
Надеюсь, в примере - только часть алгоритма, потому как массив SomeArray каждый раз переписывается.
что касается самого алгритма.
переменная цикла i - используется и во внешнем цикле, и во внутреннем, результат - лень просчитывать, проще исправить ошибку и посмотроеть, что получится

Почему бы алгоритм не вывернуть. Сделать так:
Код: Выделить всё
Fetch First From TblValue_1
while not eot(TblValue_1)
i = TblValue_1.i_col
j = TblValue_1.j_row
select * from TblValue_1 into _tmp_sel noselect where i_col in (i-1, i, i+1) and j_row in (j-1, j, j+1)
iCountElements = tableinfo(_tmp_sel, TAB_NFO_NROWS)
redim SomeArray( iCountElements )
for k = 1 to iCountElements
fetch rec k from _tmp_sel
SomeArray( k ) = _tmp_sel.f_Value
next
close table _tmp_sel
' здесь я, надеюсь, массив SomeArray как то используется, потому что на следующей строке он перепишется
' в исходном алгоритме он переписывался бы в iMaxY*iMaxX раз больше :)
Fetch next From TblValue_1
wend
и последнее:
описание
по-моему не очень эффективно реализуется операторомНеобходимо получить для каждой строки массив SomeArray() as float, состоящий элементов имеющих соседние значения i_col или i_row.
WHERE (i_col >= (i - 1) AND i_col <= (i + 1) AND i_row >= (j- 1) AND i_row <= (j + 1))
-
- Новоприбывший
- Сообщения: 13
- Зарегистрирован: 04 июл 2010, 19:53
- Репутация: 0
Re: Медленный запрос - оптимизация
Спасибо большое. Скорость обработки возросла.
Код писался на форуме, в качестве примера, поэтому наименования переменных в циклах по невнимательности могут совпадать.
Существует необходимость поиска элементов в формате:
где k не всегда = 1, поэтому так и написал условие выборки
Пошел изучать справочник
Код писался на форуме, в качестве примера, поэтому наименования переменных в циклах по невнимательности могут совпадать.
Существует необходимость поиска элементов в формате:
Код: Выделить всё
WHERE (i_col >= (i - k) AND i_col <= (i + k) AND i_row >= (j- k) AND i_row <= (j + k))
Пошел изучать справочник
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя