MS SQL Server 2000, вопросы производительности
Так а вопрос-то в чем?
Покажи планы запросов. Возможно, придется поставить хинт на последний джоин.
Так а вопрос-то в чем?Найди слова "Собственно, вопрос в следующем."
Тогда давай план запроса, без него будут лишь догадки
ага, а лучше скрипт, чтобы у себя твою тестовую ситуацию погонять
Тогда давай план запроса, без него будут лишь догадкиБлин, как бы его ещё в удобном виде получить... Как придумаю, напишу. В общем-то, по плану всё не так должно быть. Пока что приведу статистику.
Вот запрос с join внутри:
(99962 row(s) affected)
Table 'Card'. Scan count 2, logical reads 4538, physical reads 0, read-ahead reads 0.
Table 'CardEvent'. Scan count 1, logical reads 11023, physical reads 0, read-ahead reads 0.
SQL Server Execution Times:
CPU time = 14781 ms, elapsed time = 20781 ms.
Вот запрос без join внутри:
(99962 row(s) affected)
Table 'Card'. Scan count 1, logical reads 4034, physical reads 0, read-ahead reads 0.
Table 'CardEvent'. Scan count 1, logical reads 11023, physical reads 0, read-ahead reads 0.
SQL Server Execution Times:
CPU time = 20125 ms, elapsed time = 132753 ms.
сделай команду SET SHOWPLAN_TEXT ON
сделай команду SET SHOWPLAN_TEXT ONА толку только от текста-то?
Edit Хотя, мб и есть... Ща запостю.
|--Hash Match(Inner Join, HASH:([crd].[id])=([crd_join].[id] RESIDUAL:([crd].[id]=[crd_join].[id]
|--Hash Match(Inner Join, HASH:([ce].[card])=([crd].[id] RESIDUAL:([crd].[id]=[ce].[card]
| |--Compute Scalar(DEFINE:([Expr1003]=If ([Expr1029]=0) then NULL else [Expr1030], [Expr1004]=If ([Expr1031]=0)
then NULL else [Expr1032]
| | |--Hash Match(Aggregate, HASH:([ce].[card] RESIDUAL:([ce].[card]=[ce].[card]) DEFINE:([Expr1002]=SUM(If ([ce].
[eventtype]='pac') then 1 else 0 [Expr1029]=COUNT_BIG(If ([ce].[eventtype]='pac') then [ce].[sum] else 0.000000000
[Expr103
| | |--Index Seek(OBJECT:([RestoCRM].[dbo].[CardEvent].[CardEventIndex] AS [ce] SEEK:([ce].[date] >= 'Jan 1
2005 12:00AM' AND [ce].[date] <= 'Mar 1 2005 12:00AM') ORDERED FORWARD)
| |--Index Scan(OBJECT:([RestoCRM].[dbo].[Card].[Card_number] AS [crd]
|--Clustered Index Scan(OBJECT:([RestoCRM].[dbo].[Card].[PK__Card__76CBA758] AS [crd_join]
И без джойна, который выполняется в разы медленнее:
|--Hash Match(Inner Join, HASH:([ce].[card])=([crd_join].[id] RESIDUAL:([ce].[card]=[crd_join].[id]
|--Compute Scalar(DEFINE:([Expr1002]=If ([Expr1020]=0) then NULL else [Expr1021], [Expr1003]=If ([Expr1022]=0) then
NULL else [Expr1023]
| |--Hash Match(Aggregate, HASH:([ce].[card] RESIDUAL:([ce].[card]=[ce].[card]) DEFINE:([Expr1001]=SUM(If ([ce].
[eventtype]='pac') then 1 else 0 [Expr1020]=COUNT_BIG(If ([ce].[eventtype]='pac') then [ce].[sum] else 0.000000000 [Expr1021]=SU
| |--Index Seek(OBJECT:([RestoCRM].[dbo].[CardEvent].[CardEventIndex] AS [ce] SEEK:([ce].[date] >= 'Jan 1 2005
12:00AM' AND [ce].[date] <= 'Mar 1 2005 12:00AM') ORDERED FORWARD)
|--Clustered Index Scan(OBJECT:([RestoCRM].[dbo].[Card].[PK__Card__76CBA758] AS [crd_join]
Оставить комментарий
kokoc88
Имеются следующие объекты на сервере. (Они генерируются Hibernate.) Таблица описания карты клиента, размер таблицы для тестирования - 100.000 строк, clustered index по столбцу id.Таблица описания транзакции по карте, размер таблицы для тестирования - 20.000.000 строк.
Индекс для таблицы CardEvent по date, card, eventtype, sum.
Стлобец eventtype бывает либо 'pac', дибо 'dap'. Задача - написать запрос, который подсчитает количество 'pac', сумму столбца sum отдельно для 'pac' и 'dap', выберет наибольшую date у всех 'pac' с группировкой по id карты клиента. В том же запросе надо выбрать ф.и.о. клиента и номер карты, всё это за некоторый период времени, определённый date в таблице транзакций. Собственно, вопрос в следующем. Если писать запрос вот так:
Запрос будет выполняться примерно в пять раз быстрее, чем вот так: