Можно ли упростить этот SQL-запрос? - PullRequest
1 голос
/ 23 января 2010

У меня есть запрос Sql:

select * from contactmeta
WHERE
contactmeta.contact_id in 
(
select tob.object_id from tagobject tob, tag t, taggroup tg 
where tob.tag_id = t.tag_id
and t.tag_group_id = tg.tag_group_id
and tob.object_type_id = 14 
and tg.org_id = contactmeta.group_id 
and (t.name like '%campaign%')
)
AND
contactmeta.contact_id in 
(
select tob.object_id from tagobject tob, tag t, taggroup tg 
where tob.tag_id = t.tag_id 
and t.tag_group_id = tg.tag_group_id
and tob.object_type_id = 14 
and tg.org_id = contactmeta.group_id 
and (t.name like '%bounced%')
)

Моя проблема заключается в том, что мне нужно упростить часть запроса внутри предложения WHERE (я не могу сделать еще одно соединение с таблицей contactmeta и т. Д.). Это потому, что предложение WHERE динамически создается на статическом SQL в противном случае.

Вы можете видеть, что оба условия where практически одинаковы, за исключением условия t.name.

Спасибо за ваше время

SK

Ответы [ 3 ]

2 голосов
/ 23 января 2010

Как уже упоминалось, вложенные элементы в предложении WHERE не совпадают.

Я не уверен, что вы подразумеваете под "упрощенным", упрощенным каким образом? Менее многословно? Менее сложный план запроса? Больше производительности? Другими словами, какую проблему вы пытаетесь решить?

Некоторые идеи:

  • Вы можете создать представление для вашего суб-выбор (или суб-выбор, если разница между двумя на цель), которая уменьшит подробности сообщений.

  • Получить план запроса и искать сканы таблицы.

  • Рассмотрите возможность использования полнотекстовой индексации а не как с джокером в начало шаблона, как это требует, чтобы весь индекс был отсканировано (при условии наличия индекса на колонке) - если нет индекс, а затем добавить один.

2 голосов
/ 23 января 2010

на самом деле это не намного проще (с точки зрения кода), но будет более производительным, поскольку вы используете объединения, а не оператор IN:

select contactmeta .* from contactmeta 

inner join tagobject tob, tag t, taggroup tg  
on tob.tag_id = t.tag_id 
and t.tag_group_id = tg.tag_group_id 
and tob.object_type_id = 14  
and tg.org_id = contactmeta.group_id  
and (t.name like '%campaign%')

inner join tagobject tob2, tag t2, taggroup tg2  
on tob2.tag_id = t2.tag_id 
and t2.tag_group_id = tg2.tag_group_id 
and tob2.object_type_id = 14  
and tg2.org_id = contactmeta.group_id  
and (t2.name like '%bounced%') 

РЕДАКТИРОВАТЬ : если это невозможно (из-за ваших комментариев об ограничениях JOIN), вы можете абстрагировать часть логики в представления, например

create view myView 
as
select * from tagobject tob, tag t, taggroup tg  
    on tob.tag_id = t.tag_id 
    and t.tag_group_id = tg.tag_group_id

, а затем используйте это представление в исходном sql.

0 голосов
/ 23 января 2010

Попробуйте это:

select * from contactmeta
WHERE
contactmeta.contact_id in 
(
select tob.object_id from tagobject tob, tag t, taggroup tg 
where tob.tag_id = t.tag_id
and tob.object_type_id = 14 
and tg.org_id = contactmeta.group_id 
and (
   (t.tag_group_id = tg.tag_group_id and t.name like '%campaign%')
   or
   (tob.tag_id = t.tag_id and t.name like '%bounced%')
)
)
...