оракул возвращает все строки из таблицы, если - PullRequest
0 голосов
/ 14 ноября 2018

Извините, мое описание отстой, но проблему легко объяснить.У меня есть массивная таблица (более 2 млрд строк) с именем BigTable, которая разбита по дате и выглядит следующим образом:

ID    Object   Date
---   -------  ----------
1     A         2018-10-01
1     B         2018-10-01 
1     C         2018-10-01
1     D         2018-10-01
2     M         2018-10-01
2     N         2018-10-01
2     O         2018-10-01 
3     X         2018-10-01
3     B         2018-10-01

Мне нужен SQL, который возвращает ВСЕ строки для идентификатора, где Object = "B" идата = '2018-10-01' Следовательно, результат будет:

ID    Object   Date
---   -------  ----------
1     A         2018-10-01
<b>1     B         2018-10-01 </b>
1     C         2018-10-01
1     D         2018-10-01
3     X         2018-10-01
<b>3     B         2018-10-01</b>

SQL достаточно прост, просто присоедините таблицу к себе:

SELECT t2.id,t2.object, t2.date
FROM BigTable T1
join BigTable T2 on t2.id = t1.id
   AND t2.transaction_date = '01-OCT-2018'
   AND t2.object = 'B'
where t1.date = '01-OCT-2018'

Это, однако, выполняетсядля ЧАСОВ .Подзапрос не делает его лучше.Какой самый эффективный эффективный способ вернуть все строки для идентификатора, который содержит объект = 'B'?

Ответы [ 3 ]

0 голосов
/ 14 ноября 2018

Вы можете попробовать оконные функции:

SELECT t.id, t.object, t.date
FROM (SELECT t.*,
             SUM(CASE WHEN t.object = 'B' THEN 1 ELSE 0 END) OVER (PARTITION BY t.id, t.transaction_date) as cnt
      FROM BigTable t
      WHERE t.transaction_date = DATE '2018-10-01'
     ) t
WHERE cnt > 0;

Одна из возможностей состоит в том, что вы неправильно понимаете разбиение, и все содержимое таблицы читается в вашем запросе.

0 голосов
/ 15 ноября 2018

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

Алгоритмы неявного преобразования могут изменяться выпуски программного обеспечения и среди продуктов Oracle. Поведение явного конверсии более предсказуемы.

Если в выражении индекса происходит неявное преобразование типа данных, База данных Oracle может не использовать индекс, поскольку он определен для тип данных перед преобразованием. Это может оказать негативное влияние на производительность.

Таким образом, предпочтительно использовать стандартные даты ANSI

SELECT t2.id,t2.object, t2.date
FROM BigTable T1
join BigTable T2 on t2.id = t1.id
   AND t2.transaction_date = DATE '2018-10-01'
   AND t2.object = 'B'
where t1.date = DATE '2018-10-01'

Также, как уже предлагалось в комментариях, создайте LOCAL INDEX для (date, id, transaction_date, object), чтобы еще больше повысить скорость сканирования с использованием индекса вместе с сокращением раздела.

0 голосов
/ 14 ноября 2018

Я предполагаю, что у вас есть хорошая индексация ... Нет гарантий, что это поможет, но вы пробовали полусоединение:

select
  t1.*
from BigTable T1
where
  t1.transaction_date = '01-OCT-2018' and
  exists (
    select null
    from BigTable T2
    where
      t2.transaction_date = t1.transaction_date and
      t2.transaction_date = '01-OCT-2018'
      t2.object = 'B'
)

Преимущество полусоединения состоит в том, что как только он находит совпадение, он должен "перестать смотреть".

Объединение на дату транзакции может показаться излишним, но попробуйте оба способа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...