Вот три интересных способа
ar = [
[ 0, 1, 2, 3, 4],
[15, 16, 17, 18, 5],
[14, 23, 24, 19, 6],
[13, 22, 21, 20, 7],
[12, 11, 10, 9, 8]]
def print_spiral(ar):
"""
assuming a rect array
"""
rows, cols = len(ar), len(ar[0])
r, c = 0, -1 # start here
nextturn = stepsx = cols # move so many steps
stepsy = rows-1
inc_c, inc_r = 1, 0 # at each step move this much
turns = 0 # how many times our snake had turned
for i in range(rows*cols):
c += inc_c
r += inc_r
print ar[r][c],
if i == nextturn-1:
turns += 1
# at each turn reduce how many steps we go next
if turns%2==0:
nextturn += stepsx
stepsy -= 1
else:
nextturn += stepsy
stepsx -= 1
# change directions
inc_c, inc_r = -inc_r, inc_c
print_spiral(ar)
output:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
def print_spiral(ar, sr=0, sc=0, er=None, ec=None):
er = er or len(ar)-1
ec = ec or len(ar[0])-1
if sr > er or sc > ec:
print
return
# print the outer layer
top, bottom, left, right = [], [], [], []
for c in range(sc,ec+1):
top.append(ar[sr][c])
if sr != er:
bottom.append(ar[er][ec-(c-sc)])
for r in range(sr+1,er):
right.append(ar[r][ec])
if ec != sc:
left.append(ar[er-(r-sr)][sc])
print " ".join([str(a) for a in top + right + bottom + left]),
# peel next layer of onion
print_spiral(ar, sr+1, sc+1, er-1, ec-1)
Наконец, вот небольшой фрагмент, чтобы сделать это, но не эффективно, но весело :), в основном он печатает верхний ряд и вращает весь прямоугольник против часовой стрелки и повторяет
def print_spiral(ar):
if not ar: return
print " ".join(str(a) for a in ar[0]),
ar = zip(*[ reversed(row) for row in ar[1:]])
print_spiral(ar)
из or_log_all_proc, or_proc, or_log, Patient
blockquote>Ваш SELECT не содержит критериев объединения , поэтому он будет генерировать продукт из все записи из трех из этих таблиц и набор результатов любой таблицы фильтруются предложениями LIKE. Это корень вашей проблемы с производительностью.
Решение довольно простое. Правильно объединяйте таблицы, используя соответствующие ключевые столбцы.
Кстати, это преимущество использования синтаксиса соединения ANSI 92. Делая тип объединения явным, мы должны написать CROSS JOIN, если мы действительно хотим сгенерировать продукт, и не позволяет нам сделать это случайно.
Ожидать, что LIKE '% any%' будет быстрым, также бесполезно
blockquote>До определенного момента. Скорее всего, это полное сканирование таблицы, но это индексированный столбец, тогда мы можем получить полное быстрое сканирование. Даже если это просто FTS, это не обязательно катастрофично, особенно если стол маленький или нарро. Как с большинством задач настройки, это действительно зависит от деталей.
LIKE
все равно будет медленно, не так ли? Хотя, если вы уверены, что именно OR
вызывает проблемы, попробуйте UNION
, например
select pat_mrn_id,surgery_date, proc_name
from or_log_all_proc, or_proc, or_log, patient
where upper(proc_name) like ('%CRANIOTOMY ANEURYSM%')
union all
select pat_mrn_id,surgery_date, proc_name
from or_log_all_proc, or_proc, or_log, patient
where upper(proc_name) like ('CLIPPING%ANEURYSM')
Кроме того, я думаю, что это не тот запрос, который вы действительно используете - в предложении FROM есть 4 таблицы без каких-либо объединений - декартово произведение не лучший выбор.
Вместо LIKE
используйте регулярные выражения. Но что более важно, вы пропускаете JOIN
условия:
select pat_mrn_id,surgery_date, proc_name
from or_log_all_proc join
or_proc
on ???? join
or_log
on ????
patient
on ????
where regexp_like(upper(proc_name), '(CRANIOTOMY ANEURYSM)|(CLIPPING.*ANEURYSM)');
Гораздо более вероятно, что проблема производительности связана с отсутствием JOIN
условий, чем LIKE
.
Попробуйте union all
вместо or
для лучшей производительности
select pat_mrn_id,surgery_date, proc_name
from or_log_all_proc, or_proc, or_log, patient
where
upper(proc_name) like ('CLIPPING%ANEURYSM')
union all
select pat_mrn_id,surgery_date, proc_name
from or_log_all_proc, or_proc, or_log, patient
where upper(proc_name) like ('%CRANIOTOMY ANEURYSM%')
Также я думаю, что вы забыли соединить таблицы, используя уникальные идентификаторы