Как ускорить простое соединение - PullRequest
11 голосов
/ 27 мая 2009

Я плохо разбираюсь в SQL.

Я ищу способ ускорить простое соединение, как это:

SELECT
    E.expressionID,
    A.attributeName,
    A.attributeValue
FROM 
    attributes A
JOIN
    expressions E
ON 
    E.attributeId = A.attributeId

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

Я имею в виду индексы - если бы я ускорил выборку для отдельных таблиц, я бы, вероятно, поместил некластеризованные индексы в expressionID для таблицы выражений и другой в (attributeName, attributeValue) для таблицы атрибутов - но я не знать, как это может применяться к объединению.

EDIT : у меня уже есть кластеризованный индекс для expressionId (PK), attributeId (PK, FK) в таблице выражений и другой кластеризованный индекс в attributeId (PK) в таблице атрибутов

Я видел этот вопрос, но я прошу что-то более общее и, вероятно, гораздо более простое.

Любая помощь приветствуется!

Ответы [ 7 ]

17 голосов
/ 27 мая 2009

Вы определенно хотите иметь индексы для attributeID для таблиц attributes и expressions. Если у вас пока нет этих индексов, я думаю, вы увидите значительное ускорение.

6 голосов
/ 27 мая 2009

На самом деле, поскольку возвращено так мало столбцов, я бы рассмотрел покрытый индекс для этого запроса

т.е. индекс, который включает в себя все поля в запросе.

3 голосов
/ 27 мая 2009

Вам нужно позаботиться о индексах, плане запросов и статистике.

Поместить индексы на attributeId. Или убедитесь, что существуют индексы, где attributeId является первым столбцом в ключе (SQL Server все еще может использовать индексы, если это не 1-й столбец, но он не такой быстрый).

Выделите запрос в Query Analyzer и нажмите ^ L, чтобы увидеть план. Вы можете увидеть, как таблицы объединяются. Почти всегда, использование индексов лучше, чем нет (есть несколько случаев, когда таблица достаточно мала, индексы могут замедлить вас - но пока, просто знайте, что 99% временных индексов хорошо).

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

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

2 голосов
/ 27 мая 2009

Бьюсь об заклад, ваша проблема в огромном количестве строк, которые вставляются в эту временную таблицу. Можно ли как-нибудь добавить предложение WHERE перед SELECT каждой строкой в ​​базе данных?

1 голос
/ 28 мая 2009

Если я правильно понимаю вашу схему, вы утверждаете, что ваши таблицы выглядят примерно так:

Expressions: PK - ExpressionID, AttributeID
Attributes:  PK - AttributeID

Предполагая, что каждый PK является кластеризованным индексом, это все равно означает, что в таблице выражений требуется сканирование индекса. Возможно, вы захотите создать индекс для таблицы Выражения , например: AttributeID, ExpressionID . Это поможет остановить сканирование индекса, которое в данный момент выполняется.

1 голос
/ 27 мая 2009

Еще одна вещь, которую нужно сделать, это добавить несколько индексов, таких как:

attributes.{attributeId, attributeName, attributeValue}
expressions.{attributeId, expressionID}

Это хак! Но полезно, если это последнее средство.

Для этого создается план запроса, на который индексы могут "полностью ответить". Обычно индекс фактически вызывает двойной ввод-вывод в указанном выше запросе: один для попадания в индекс (т. Е. Для проверки в таблице), другой для извлечения фактической строки, на которую ссылается индекс (для извлечения attributeName и т. Д.).

Это особенно полезно, если "атрибуты" или "выражения" - это широкая таблица. То есть таблица, из которой дорого выбираются строки.

Наконец, лучший способ ускорить ваш запрос - добавить предложение WHERE!

0 голосов
/ 24 апреля 2019

Советы

Если вы хотите ускорить запрос с помощью соединения:

Для "внутреннего соединения / соединения",
Не используйте условие «вместо», вместо этого используйте его в состоянии «ВКЛ».
Например:

         select id,name from table1 a  
       join table2 b on a.name=b.name
       where id='123'

     Try,

        select id,name from table1 a  
       join table2 b on a.name=b.name and a.id='123'

Для "левого / правого соединения",
Не используйте в состоянии «ВКЛ.», Потому что если вы используете соединение влево / вправо, оно получит все строки для любой таблицы. Итак, попробуйте использовать условие «Где»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...