Ответ 1
Вы определенно хотите иметь индексы на attributeID
в таблице attributes
и expressions
. Если у вас сейчас нет этих индексов, я думаю, вы увидите большое ускорение.
Я плохо разбираюсь в SQL.
Я ищу способ ускорить простое соединение следующим образом:
SELECT
E.expressionID,
A.attributeName,
A.attributeValue
FROM
attributes A
JOIN
expressions E
ON
E.attributeId = A.attributeId
Я делаю это десятки тысяч раз, и это становится все больше, поскольку таблица становится больше.
Я думаю, что индексы. Если бы мне нужно было ускорить выбор в одиночных таблицах, я бы, вероятно, поместил некластеризованные индексы на expressionID для таблицы выражений, а другой в (attributeName, attributeValue) для таблицы атрибутов - но я не знаете, как это может быть применимо к соединению.
EDIT. У меня уже есть кластерный индекс для выраженияId (PK), attributeId (PK, FK) в таблице выражений и другой кластеризованный индекс в атрибутеId (PK) в таблице атрибутов
Я видел этот вопрос, но я прошу что-то более общее и, вероятно, гораздо проще.
Любая помощь оценивается!
Вы определенно хотите иметь индексы на attributeID
в таблице attributes
и expressions
. Если у вас сейчас нет этих индексов, я думаю, вы увидите большое ускорение.
Фактически, поскольку возвращено так мало столбцов, я бы рассмотрел закрытый индекс для этого запроса
то есть. индекс, который включает все поля в запросе.
Некоторые вещи, о которых вам нужно заботиться, это индексы, план запросов и статистика.
Поместите индексы в атрибутId. Или убедитесь, что индексы существуют там, где attributeId является первым столбцом в ключе (SQL Server все еще может использовать индексы, если он не первый столбец, но он не так быстро).
Выделите запрос в Query Analyzer и нажмите ^ L, чтобы увидеть план. Вы можете видеть, как таблицы объединены вместе. Почти всегда, используя индексы лучше, чем нет (есть случаи, когда таблица достаточно мала, индексы могут замедлить вас - но на данный момент просто помните, что 99% индексов времени являются хорошими).
Обратите внимание на порядок соединения таблиц. SQL Server поддерживает статистику размеров таблиц и определяет, с какой из них лучше всего присоединиться. Проведите некоторое расследование внутренних процедур SQL Server для обновления статистики - это слишком долго, поэтому я не располагаю этой информацией.
Это должно заставить вас начать. Действительно, целая глава может быть написана о том, как база данных может оптимизировать даже такой простой запрос.
Я уверен, ваша проблема заключается в огромном количестве строк, которые вставляются в эту временную таблицу. Есть ли способ добавить предложение WHERE
до SELECT
каждой строки в базе данных?
Еще одна вещь, которую нужно сделать, - добавить несколько таких индексов:
attributes.{attributeId, attributeName, attributeValue}
expressions.{attributeId, expressionID}
Это взломано! Но полезно, если это в последнюю очередь.
Что это значит, это создать план запросов, который может быть "полностью удовлетворен" индексами. Как правило, индекс фактически вызывает двойной ввод-вывод в вашем предыдущем запросе: один из них попадает в индекс (т.е. Зонд в таблицу), другой - для получения фактической строки, указанной индексом (для вытягивания имени атрибута и т.д.).
Это особенно полезно, если "атрибуты" или "выражения" - это широкая таблица. То есть, таблица, которая дорого извлекает строки из.
Наконец, лучший способ ускорить запрос - добавить предложение WHERE!
Если я правильно понимаю вашу схему, вы заявляете, что ваши таблицы выглядят следующим образом:
Expressions: PK - ExpressionID, AttributeID Attributes: PK - AttributeID
Предполагая, что каждый PK является кластеризованным индексом, это все равно означает, что в таблице выражений требуется сканирование индексов. Возможно, вам стоит подумать о создании индекса в таблице выражений, например: AttributeID, ExpressionID. Это поможет остановить сканирование индексов, которое в настоящее время происходит.