2014-02-12 4 views
-1

Пожалуйста, помогите мне проверить sql, есть ли проблемы? его можно оптимизировать? Это займет много времени, но не всегда.Предложение по оптимизации SQL SQL

SELECT count(*) 
FROM DB2INST3.VWQueue1_119 
WHERE inbasketName is not null 
AND userid1 is not null 
AND nItemIndex is not null 
AND string1 is not null 
AND (F_BoundUser = ? OR F_BoundUser = ?) 
AND (F_Locked < 2) 
AND ((inbasketName='PSIQUEUE1Index') AND (inbasketName='PSIQUEUE1Index')) 

Получил снимок как:

Количества исполнений = 12942 Количества сборников
= 1 Худшего время приготовления (мс) = 6 лучшего время подготовки (мс) = 6 Внутренних строк удаленных = 0 Внутренние строк, вставленных = 0 Ряды чтения = 1399262666 Общее время исполнения (sec.microsec) = 3600,704315 Общее время пользователь процессора (sec.microsec) = 2538,101110 Общее системное время CPU (sec.microsec) = 0,191321

+0

нравится это соглашение об именовании схемы/таблицы –

+0

Это утверждение выглядит довольно простым, и оптимизация не может быть выполнена (F_Bounduser там дважды?). Судя по имени вашей таблицы, вы выбираете из представления ... вероятно, ваша проблема с производительностью. @MitchWheat - Рисунок есть VWQueue1_001 через VWQueue1_99999? – Twelfth

+0

это физическая таблица. – Sun

ответ

0

Вот упрощение запроса:

SELECT count(*) 
FROM DB2INST3.VWQueue1_119 
WHERE userid1 is not null and 
     nItemIndex is not null and 
     string1 is not null and 
     (F_BoundUser in (?, ?) and 
     (F_Locked < 2) and 
     (inbasketName = 'PSIQUEUE1Index') 

Вот изменения:

  • Условие inbasketName='PSIQUEUE1Index' упоминается дважды. Нужен.
  • Условие inbasketName is not null является избыточным, поскольку значение сравнивается со строкой.

Единственный индекс, который наиболее всего поможет: VWQueue1_119(inbasketName, F_BoundUser, F_Locked). Если в таблице большое количество других столбцов, то добавление userid1, nItemIndex и string1 создаст индекс покрытия, поэтому исходные страницы данных не будут затронуты.

0

Условия, которые используют ИЛИ в индексированном столбце, печально известны тем, что индекс не используется. К счастью, есть простое исправление.

Изменить это:

AND (F_BoundUser = ? OR F_BoundUser = ?) 

Для этого:

AND F_BoundUser IN (?, ?) 

Хотя два достижения точности то же самое, что оптимизатор будет (как правило) использовать индекс с IN(), но не для OR.

Кроме того, это все равно элегантно.

Это то, что я успешно использовал много раз.

+0

Сколько накладных расходов потребуется? Когда-нибудь это займет ~ 200 мс, это имеет смысл? – Sun

+0

Нет, это не имеет смысла. Является ли одно или оба значения «null»? Может ли таблица быть заблокирована другим процессом? – Bohemian

+0

Я проверил замки, никаких проблем. – Sun

0

Вы можете рассчитывать на 0:

SELECT COUNT(0) 
... 

Если оптимизатор не в более высоком уровне, DB2 упреждающий столбцы просто сосчитать их. С помощью 0 DB2 будет использовать другие способы, например, только индексы или статистику.

Смежные вопросы