Фильтрация SQL-запроса по строке и по диапазону дат - PullRequest
3 голосов
/ 15 декабря 2010

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

Автономный запрос даты (2352 строки в 0,203 с):

select oracle_time from t_ssv_soh_packets0
where oracle_time >= TIMESTAMP '2009-01-01 00:00:00' 
AND oracle_time <= TIMESTAMP '2009-01-31 00:00:00' 

Запрос сокращения сокращения (1017 за 0,89 с):

select oracle_time from t_ssv_soh_packets0
where (rowid,0) in (select rowid, mod(rownum,50) from t_ssv_soh_packets0)

Когда я пытаюсь их объединить, это занимает вечность (48 строк за 32,547 с):

select oracle_time from t_ssv_soh_packets0
where oracle_time >= TIMESTAMP '2009-01-01 00:00:00' 
AND oracle_time <= TIMESTAMP '2009-01-31 00:00:00' 
AND (rowid,0) in (select rowid, mod(rownum,50) from t_ssv_soh_packets0)

Очевидно, что я делаю здесь что-то в корне неправильно, но я не знаю, как еще сделать запрос по дате и сократить данные.

Ответы [ 4 ]

2 голосов
/ 15 декабря 2010

Вы оцениваете логику сокращения по строкам, которые не находятся в выбранном вами диапазоне дат.

Применить логику сокращения к подзапросу, содержащему ваш диапазон дат.

СПУСТЯ: Вот что я имел в виду.

select oracle_time from (
  select oracle_time, rownum as limited_row_num
  from t_ssv_soh_packets0 
  where oracle_time >= TIMESTAMP '2009-01-01 00:00:00'  
  AND oracle_time <= TIMESTAMP '2009-01-31 00:00:00'  
) as time_range
where mod(limited_row_num,50) =  0
1 голос
/ 16 декабря 2010

Вы также можете позволить Oracle выбрать случайную выборку из результата, применив предложение SAMPLE () :

SELECT oracle_time 
FROM t_ssv_soh_packets0
WHERE ...
SAMPLE(50)

Возвращает случайным образом 50% процентов строк

1 голос
/ 15 декабря 2010

Избавьтесь от in

Зачем это использовать ?:

select oracle_time from t_ssv_soh_packets0
where (rowid,0) in (select rowid, mod(rownum,50) from t_ssv_soh_packets0)

Ваше единственное условие - мод (rownum, 50)

select * from t where mod(rownum, 50)=0

последнеестрока должна быть AND mod(rownnum,50)=0, а не самостоятельным соединением с in.

0 голосов
/ 15 декабря 2010

Благодаря указателям «Narveson» и «nate c» за указатели я наконец понял это. Вот (возможно, специфичный для Oracle) запрос, который я пришел:

select oracle_time from t_ssv_soh_packets0 where oracle_time >= TIMESTAMP '2009-01-01 00:00:00' AND oracle_time <= TIMESTAMP '2009-01-31 00:00:00' group by oracle_time, rownum having mod(rownum, 50)=0

Этот запрос возвращает 47 строк за 0,031 с. Исходный запрос времени содержал 2352 строки, так что это имеет смысл.

ORAFAQ помог мне найти окончательное решение.

...