2010-11-16 4 views
1

Две таблица:
а) svn3 с колоннами name revno compname
б) archdetails с колоннами name version compname inFlatПочему выходные данные разные для этих 2-х sql-запросов?

В случае, если не эти 2 запросов выходные один и тот же результат. Результат запроса 2 правильный. Что не так с query1?

Query1:
select sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END) from archdetails inner join svn3 on archdetails.compname=svn3.compname where archdetails.name='ant' AND version='1.4' AND (revno='r274642' OR revno='r274578' OR revno='r274533')

Query2:
select sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END) from archdetails where name='ant' AND version='1.4' AND compname IN (select compname from svn3 where revno ='r274642' OR revno='r274578' OR revno='r274533')

ответ

2

Если svn3 имеет более чем одну строку с тем же compname, которые также имеют один из запрошенных revno значений, то запрос 1 будет считать каждый svn3 строку один раз. Запрос 2 будет считать только один раз compname. Предложение IN исключает любые дубликаты compname записей во втором запросе.

Если вы не хотите считать дубликаты compname записей, вам необходимо сгруппировать их в подзапрос. Один из способов сделать это - использовать предложение IN, как и в запросе 2. Другой вариант - использовать GROUP BY в подзапросе и называть этот подзапрос. Затем присоедините именованный подзапрос к таблице archdetails.

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

Я видел несколько комментариев, что EXISTS иногда быстрее, чем IN, но я не видел никаких доказательств, подтверждающих это. Вы можете поэкспериментировать с этим.

+0

Да, вы правы. Как я могу изменить запрос 1 для этого? Запрос Beacuse 2 слишком медленный даже после индексации – Gaurav

+2

Пробовал ли вы использовать query2, но с использованием оператора 'exists' вместо условия 'in'? Как правило, это намного лучше с точки зрения производительности. –

+0

Спасибо, попробуем использовать EXISTS. – Gaurav

0

Просмотрев другие ответы, теперь я думаю, что это вряд ли объяснение, но будет держать его вокруг в случае, если не ...

Я предполагаю, что это вызвано значениями NULL где-то (винить его в NULL - тактика, которая обычно работает). Имеются ли значения archdetails.compname или svn3.compname, и если да, то должны ли в таблицах содержать нулевые значения? Если nulls действительно существуют, вам нужно выяснить, что именно вы хотите, когда сравниваются значения NULL.

Если это вызвано нулевыми значениями, здесь может быть сыграна ваша установка ANSI_NULLS.

+0

Здесь нет значений NULL. – Gaurav

2

Нет, два запроса не совпадают - первый запрос заключается в объединении записей svn3 в compname, для версии «1.4» и одном из трех значений revno. Если существует несколько записей svn3 для заданного имени (с версией «1.4» и любым из значений 3 revno), тогда query1 будет возвращать значительно больше результатов.

Возможное решение: изменение

sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END)

к

count(distinct CASE WHEN inFlat=1 THEN archdetails.compname END)

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

+0

Я предполагаю, что это происходит. Любой способ исправить это, используя какую-либо другую форму присоединения или изменения этого? – Gaurav

+0

@Gaurav: см. Отредактированный ответ. –

+0

Спасибо, проверьте и сообщите о результатах. – Gaurav

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