Условие в СОЕДИНЕНИИ или ГДЕ

String.Length не учитывает суррогатные пары; однако метод StringInfo.LengthInTextElements делает.

StringInfo.SubstringByTextElements похож на String.Substring, но он работает с «текстовыми элементами», такими как суррогатные пары и символы объединения, а также обычные символы. Функциональность обоих этих методов основана на методе StringInfo.ParseCombiningCharacters, который извлекает начальный индекс каждого текстового элемента и сохраняет их в частном массиве.

«.NET Framework определяет текстовый элемент как единицу текста, отображаемую в виде одного символа, то есть графемы. Текстовый элемент может быть базовым символом, суррогатной парой или комбинацией последовательность символов. " - http://msdn.microsoft.com/en-us/library/system.globalization.stringinfo.aspx

169
задан Steve Dignan 19 June 2009 в 16:49
поделиться

8 ответов

Реляционная алгебра допускает взаимозаменяемость предикатов в предложении WHERE и INNER JOIN , поэтому даже INNER JOIN запросы с предложениями WHERE оптимизатор может переупорядочить предикаты так, чтобы они уже могли быть исключены во время процесса JOIN .

Я рекомендую вам писать запросы наиболее удобочитаемым способом.

Иногда это включает в себя сделать INNER JOIN относительно «неполным» и поместить некоторые критерии в WHERE просто для создания списков критериев фильтрации проще в обслуживании.

Например, вместо:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

Напишите:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

Но это, конечно, зависит от ситуации.

142
ответ дан 23 November 2019 в 20:52
поделиться

Для внутренних объединений я действительно не заметил разницы (но, как и в случае со всеми характеристиками настройки, вам необходимо сверяться с вашей базой данных в ваших условиях).

Однако то, где вы помещаете условие, имеет огромное значение, если вы используете левое или правое объединение. Например, рассмотрим эти два запроса:

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE ORD.OrderDate >'20090515'

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
AND ORD.OrderDate >'20090515'

Первый предоставит вам только те записи, которые имеют заказ, датированный позже 15 мая 2009 г., таким образом преобразовав левое соединение во внутреннее соединение. Второй предоставит эти записи плюс всех клиентов без заказов. Набор результатов сильно различается в зависимости от того, где вы поставили условие. (Выберите * только для примера, вы, конечно, не должны использовать этот код в производственном коде.) Исключение составляют случаи, когда вы хотите видеть только записи в одной таблице, а не другую. Затем вы используете предложение where для условия, а не для соединения.

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE ORD.OrderID is null
115
ответ дан 23 November 2019 в 20:52
поделиться

Большинство продуктов СУБД оптимизируют оба запроса одинаково. В «Настройка производительности SQL» Питера Гулуцана и Труди Пельцер они протестировали несколько марок СУБД и не обнаружили разницы в производительности.

Я предпочитаю хранить условия соединения отдельно от условий ограничения запросов.

Если вы используете ] OUTER JOIN иногда необходимо указать условия в предложении соединения.

24
ответ дан 23 November 2019 в 20:52
поделиться

Я предпочитаю JOIN для объединения полных таблиц / представлений, а затем использовать WHERE, чтобы ввести предикат результирующего набора.

Это кажется синтаксически более чистым.

3
ответ дан 23 November 2019 в 20:52
поделиться

WHERE будет фильтровать после того, как JOIN произошло.

Фильтровать JOIN, чтобы предотвратить добавление строк во время процесса JOIN.

10
ответ дан 23 November 2019 в 20:52
поделиться

Я обычно вижу повышение производительности при фильтрации соединения. Особенно, если вы можете объединить индексированные столбцы для обеих таблиц. Вы должны иметь возможность сократить количество логических чтений, когда большинство запросов тоже делают это, что в среде с большим объемом данных является гораздо лучшим показателем производительности, чем время выполнения.

Меня всегда слегка забавляет, когда кто-то демонстрирует результаты своих тестов SQL. и они выполнили обе версии sproc 50 000 раз в полночь на сервере разработки и сравнили среднее время.

2
ответ дан 23 November 2019 в 20:52
поделиться

На мой взгляд, соединения выполняются быстрее, когда у вас есть стол побольше. На самом деле это не такая уж большая разница, особенно если вы имеете дело с довольно маленьким столом. Когда я впервые узнал о соединениях, мне сказали, что условия в соединениях точно такие же, как условия в предложении where, и что я мог бы использовать их взаимозаменяемо, если бы в предложении where было указано, для какой таблицы выполнять условие.

0
ответ дан 23 November 2019 в 20:52
поделиться

Помещение условия в соединение мне кажется "семантически неправильным", поскольку JOIN не для этого предназначены. Но это очень качественно.

Дополнительная проблема: если вы решите переключиться с внутреннего соединения на, скажем, правильное соединение, наличие условия внутри JOIN может привести к неожиданным результатам.

0
ответ дан 23 November 2019 в 20:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: