Запрос, который выполняется медленно как один запрос, но за доли секунды, если выполняется в два этапа - PullRequest
3 голосов
/ 09 августа 2011

У меня есть два представления в базе данных ORACLE:

The view USERS with columns:
UserId | GroupId | Details

, где есть 1 запись для каждого пользователя, всего 40 000, и в каждой группе около 1-30 пользователей.

и

The view SUMMARY with columns:
UserId | Summary 

где есть 1 запись для каждого пользователя

ОБЗОР очень сложный, но все же довольно быстрый, когда я запрашиваю его на основе пользователя.То есть:

select * from SUMMARY where UserId='some_user_id'

выполняет за 0,1 с

Представление USERS довольно простое (объединяет все таблицы USERS_TYPE1 и USERS_TYPE2) и запрос типа:

select * from USERS where GroupId='some_group_id'

выполняет за 0,02 с

Теперь вот уловка, когда я это делаю:

select * from USERS JOIN SUMMARY 
ON USERS.UserId = SUMMARY.UserId
WHERE USERS.GroupId = 'some_group_id'

Я получаю УЖАСНУЮ производительность 90 секунд - хотя всего 3пользователи в группе.

Это должно занять всего лишь долю секунды, если сначала будут найдены идентификаторы пользователей, а затем в таблицу SUMMARY поступают запросы с этими идентификаторами пользователей.Есть ли способ, которым я могу намекнуть БД, чтобы сделать это?

У меня есть индексы, основанные на UserId, GroupId и (GroupId, UserId) для всех базовых таблиц.

((Это довольно сложновоспроизводить простым способом, поскольку в сложном представлении есть много базовых таблиц. У меня есть несколько версий представления SUMMARY. В некоторых случаях (в зависимости от того, как построено резюме) оно перестает быть ужасным, когда я материализую представление Users,но в других случаях это не так.))

Ответы [ 2 ]

1 голос
/ 10 августа 2011

Вы можете попробовать

  SELECT * 
  FROM
    (select * from USERS
    WHERE USERS.GroupId = 'some_group_id') u,
    summary
  WHERE USERS.UserId = SUMMARY.UserId

Также укажите, какие именно столбцы вы хотите, вместо того, чтобы выбирать * (вам явно не нужны обе версии UserId)

МОЖЕТ стоить попробовать

  SELECT * 
  FROM
    (select users.*, rownum rn from USERS
    WHERE USERS.GroupId = 'some_group_id') u,
    summary
  WHERE USERS.UserId = SUMMARY.UserId

, что заставит его сначала оценить встроенное представление.

0 голосов
/ 09 августа 2011

Представления по представлениям ... лучше избегать, либо обрабатывать очень (очень) осторожно.Большие проблемы с производительностью, и это сложная тема, но вот некоторая основная информация:

http://www.dba -oracle.com / concepts / views.htm http://www.dba -oracle.com / art_hints_views.htm

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