SQL считает производительность (sql 2000) - PullRequest
1 голос
/ 25 июня 2009

Я видел в посте что-то вроде «небольшое изменение, которое вы сделали, которое увеличило производительность вашего приложения», комментарий об изменении:

SELECT U.userid,groups_in=(
    SELECT COUNT(*) 
    FROM usersgroup 
    WHERE userid=U.userid) 
FROM tbl_users U 

до:

SELECT U.userid, groups_in 
FROM users U 
LEFT JOIN (
    select userid, groups_in=count(*) 
    from usersgroup 
    group by userid) GROUPS 
    ON GROUPS.userid = U.userid

И я подумал: «О, это то, что я делал неправильно!», Однако я пробовал оба запроса в одной и той же среде, и оба дают мне одинаковое время выполнения, и план выполнения БД выглядит точно так же .

Есть ли лучший способ сделать ту же операцию? эти запросы абсолютно нормально?

Ответы [ 6 ]

2 голосов
/ 25 июня 2009

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

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

1 голос
/ 25 июня 2009

Попробуйте:

SELECT U.userid, COUNT(G.userid) as groups_in
FROM users U LEFT JOIN usersgroup G ON G.userid = U.userid
GROUP BY U.userid;

Это позволяет избежать подзапросов - что очень плохо для оптимизатора.

Убедитесь, что у вас есть индекс в столбце "userid" в обеих таблицах

0 голосов
/ 25 июня 2009

Следует учитывать одно обстоятельство: оптимизатор запросов SQL Server основан на стоимости. Другими словами, он проверяет ваш запрос, стратегии индексации, статистику и другие факторы, чтобы создать план запроса перед его выполнением. Вам нужен репрезентативный набор данных для проверки вашего запроса.

0 голосов
/ 25 июня 2009

Кажется, это самый естественный способ написать это:

SELECT U.userid, COUNT(g.userid) as groups_in
FROM users U 
LEFT JOIN usersgroup G ON G.userid = U.userid
GROUP BY U.userid

COUNT (*) вернет 1 даже для пользователей без группы пользователей. COUNT (g.userid) возвращает 0, если группа пользователей не найдена.

0 голосов
/ 25 июня 2009

Альтернативный метод - суммирование количества строк, которые не равны нулю.

select 
    u.userId
,   sum(case when ug.userId is not null then 1 else 0 end) 'groups_in'
from
    users u
    left join usergroups ug on u.userId = ug.userId
group by
    u.userId
0 голосов
/ 25 июня 2009

вам действительно нужно использовать count (*)?

Вы можете значительно повысить производительность, если вы назовете столбец в звездочке звездочкой или используете count (1)

и я бы обычно избегал выбора в выборе

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