Несколько запросов, чтобы избежать объединений? - PullRequest
4 голосов
/ 28 февраля 2009

Я заметил, как только я добавил соединения к некоторым из моих запросов, время, которое потребовалось для их выполнения, было больше, чем просто выполнение нескольких запросов.

Время включает в себя загрузку страницы и в среднем более 20 загрузок страницы.

7-9 запросов без объединений
159ms

3 запроса с 2 объединениями
235ms

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

EDIT

Я создам некоторую ложную информацию ради вопроса.

Объекты таблицы
ID (int, identity, PK, кластерный индекс)
UserID (int, некластеризованный индекс)
CategoryID (int, некластеризованный индекс)

Таблица пользователей
ID (int, identity, PK, кластерный индекс)

Категории таблиц
ID (int, identity, PK, кластерный индекс)

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

План запроса для объединения показывает 42% выполненных за 2 поиска кластеризованного индекса, 23% - сканирование кластеризованного индекса, а остальное - сортировка по Top N

Ответы [ 6 ]

5 голосов
/ 28 февраля 2009

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

Анализ запросов должен быть первым шагом здесь. Я не очень знаком с вашим конкретным видом SQL, но, скорее всего, это будет что-то вроде EXPLAIN.

Если бы мне пришлось указать вероятного виновника на основании ограниченной информации, которую я имею здесь, это было бы отсутствием индексов. Правильно ли проиндексированы поля, к которым вы присоединяетесь? Это может получить ОГРОМНОЕ повышение производительности. Во-вторых, вы присоединяетесь к правильным полям? Например, если вы объединяете две строки вместе, ваша производительность будет намного хуже, чем при объединении целого или другого оптимизированного поля.

4 голосов
/ 28 февраля 2009

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

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

select a.Some, b.Other
from TableA a
inner join TableB b on b.Id = a.Id

Вы должны убедиться, что в поле TableB.Id есть индекс. Первичный ключ таблицы обычно получает индекс по умолчанию, но другие индексы вы должны создать самостоятельно.

2 голосов
/ 28 февраля 2009

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

Делать соединения дороже. Это не значит, что вы не должны их использовать.

Поможет увидеть SQL, который вы пишете ... (создается LINQ to SQL)

1 голос
/ 28 февраля 2009

если вы запускаете их только для получения данных в анализаторе запросов, тогда подходит несколько запросов, но если вы запускаете их из веб-приложения или консольного приложения, вам нужно оптимизировать их до 1 запроса. Даже если это займет немного больше времени, вы увидите прирост производительности, поскольку не обращаетесь к своей базе данных более одного раза. Чем меньше вы ударите по БД, тем лучше будет ваша производительность. Я бы поработал над тем, чтобы ваши запросы были повторными. Похоже, ваши таблицы нормализованы и проиндексированы настолько, что вы сможете получить их до одного запроса.

1 голос
/ 28 февраля 2009

Вы пробовали запускать свои запросы с помощью объединений через анализатор, чтобы узнать, что вы делаете для их оптимизации?

0 голосов
/ 13 августа 2013

Я бы попытался избавиться от всех типичных объединений. Например, я бы изменил:

select t1.id, t1.name, t2.gpa from t1 join t2 on t1.id =t2.id 

этим:

select t1.id, t1.name, t2.gpa from t1, t2 where t2.id = t1.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...