У нас есть массивный, многозадачный запрос Sybase, который мы вызываем в запросе get_safari_exploration_data
, который извлекает всякую информацию, связанную с исследователями, идущими на сафари, и все животные, с которыми они сталкиваются.Что я могу сделать, чтобы ускорить этот медленный запрос?
Этот запрос выполняется медленно, и меня попросили ускорить его. Первое, что выпрыгивает на меня, заключается в том, что не существует насущной потребности в вложенном заявлении SELECT
внутри внешнего предложения FROM
. В том, что вложенные SELECT
, также, кажется, несколько полей, которые не являются необходимыми (vegetable
, broomhilda
, devoured
и т. Д.). Я также скептически отношусь к использованию объединений («*=
» вместо «INNER JOIN ... ON»).
SELECT
dog_id,
cat_metadata,
rhino_id,
buffalo_id,
animal_metadata,
has_4_Legs,
is_mammal,
is_carnivore,
num_teeth,
does_hibernate,
last_spotted_by,
last_spotted_date,
purchased_by,
purchased_date,
allegator_id,
cow_id,
cow_name,
cow_alias,
can_be_ridden
FROM
(
SELECT
mp.dog_id as dog_id,
ts.cat_metadata + '-yoyo' as cat_metadata,
mp.rhino_id as rhino_id,
mp.buffalo_id as buffalo_id,
mp.animal_metadata as animal_metadata,
isnull(mp.has_4_Legs, 0) as has_4_Legs,
isnull(mp.is_mammal, 0) as is_mammal,
isnull(mp.is_carnivore, 0) as is_carnivore,
isnull(mp.num_teeth, 0) as num_teeth,
isnull(mp.does_hibernate, 0) as does_hibernate,
jungle_info.explorer as last_spotted_by,
exploring_journal.spotted_datetime as last_spotted_date,
jungle_info.explorer as purchased_by,
early_exploreration_journal.spotted_datetime as purchased_date,
alleg_id as allegator_id,
ho.cow_id,
ho.cow_name,
ho.cow_alias,
isnull(mp.is_ridable,0) as can_be_ridden,
ts.cat_metadata as broomhilda,
ts.squirrel as vegetable,
convert (varchar(15), mp.rhino_id) as tms_id,
0 as devoured
FROM
mammal_pickles mp,
very_tricky_animals vt,
possibly_venomous pv,
possibly_carniv_and_tall pct,
tall_and_skinny ts,
tall_and_skinny_type ptt,
exploration_history last_exploration_history,
master_exploration_journal exploring_journal,
adventurer jungle_info,
exploration_history first_exploration_history,
master_exploration_journal early_exploreration_journal,
adventurer jungle_info,
hunting_orders ho
WHERE
mp.exploring_strategy_id = 47
and mp.cow_id = ho.cow_id
and ho.cow_id IN (20, 30, 50)
and mp.rhino_id = vt.rhino_id
and vt.version_id = pv.version_id
and pv.possibly_carniv_and_tall_id = pct.possibly_carniv_and_tall_id
and vt.tall_and_skinny_id = ts.tall_and_skinny_id
and ts.tall_and_skinny_type_id = ptt.tall_and_skinny_type_id
and mp.alleg_id *= last_exploration_history.exploration_history_id
and last_exploration_history.master_exploration_journal_id *= exploring_journal.master_exploration_journal_id
and exploring_journal.person_id *= jungle_info.person_id
and mp.first_exploration_history_id *= first_exploration_history.exploration_history_id
and first_exploration_history.master_exploration_journal_id *= early_exploreration_journal.master_exploration_journal_id
and early_exploreration_journal.person_id *= jungle_info.person_id
) TEMP_TBL
Так я спрашиваю:
- Я правильно о вложенной
SELECT
? - Правильно ли я делаю ненужные поля внутри вложенных
SELECT
? - Я правильно отношусь к структуре/синтаксису/использованию соединений?
- Есть ли что-нибудь еще о структуре/характере этого запроса, который выскакивает на вас как ужасно неэффективный/медленный?
К сожалению, если не неопровержимо, прозаичный доказательство того, что разлагая этот большой запрос на меньшие запросы выгодно в долгосрочной перспективе, руководство просто не одобряет рефакторинга его на несколько более мелких запросов, так как это потребуется много времени для рефакторинга и тестирования. Заранее спасибо за любую помощь/прозрение!
Вложенный SELECT может или не может обеспечить удар производительности. Это зависит от плана выполнения (я не могу сказать вам, так как много моделей для моделирования). Если он использует временную таблицу, то обязательно удалите вложенный SELECT (вы можете узнать, используя план EXPLAIN). В противном случае дополнительные поля ничего не повредят, если они не потребуют ненужного соединения. Опять же, это зависит от того, использует ли план выполнения временную таблицу (оптимизатор удалит ненужные таблицы из запроса, если первый запрос не скопирован во временную таблицу). – jtv4k
Спасибо @ jtv4k (+1) - чтобы уточнить, вы говорите, что * если * план выполнения (который я вижу через 'EXPLAIN') показывает Sybase как использование' TEMP_TBL', тогда мне определенно нужно удалить вложенные 'SELECT'? Если это то, что вы говорите, можете ли вы объяснить, почему вложенные «SELECT» и связанные с ним «TEMP_TBL» являются «плохими» (медленными) для плана выполнения? – 2013-04-25 17:51:32
Ahhh, я начинаю «достать». Если я правильно понимаю: если подзапрос скопирован в временную таблицу, то оптимизатор не удалит unnessary join; в противном случае ненужные соединения будут оставаться частью плана выполнения, и они будут отрицательно влиять на производительность? ** Это справедливая оценка? ** Еще раз спасибо! – 2013-04-25 17:56:42