Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
Доброго времени суток! Есть проблема с запросом где использую CROSS apply. Имеется таблица Проводки куда постоянно добавляются записи...сейчас она составляет 85000 записей написал VIEW где использую CROSS apply...и этот запрос выполянется ужасно долго...иногда до минуты иногда чуть больше минуты...незнаю что делать..помогите пожалуста советом и примером что сделать...таблица растет и 85000 это ведь не так много...или я ошибаюсь..пример запроса привожу:
USE [AspProjectDb5.1]
GO
/****** Object:  StoredProcedure [dbo].[Summa]    Script Date: 03/11/2013 13:47:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		<Author,,Name>
-- Create date: <Create Date,,>
-- Description:	<Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[Summa] 
	-- Add the parameters for the stored procedure here
	/*<@Param1, sysname, @p1> <Datatype_For_Param1, , int> = <Default_Value_For_Param1, , 0>, 
	<@Param2, sysname, @p2> <Datatype_For_Param2, , int> = <Default_Value_For_Param2, , 0>*/
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

    -- Insert statements for procedure here
SELECT     v.Account, v.Quantity, cr.A, cr.B, cr.C, cr.D, cr.deb_name, cr.IdUserOwner, cr.IdUserCreator, cr.Object_Id
FROM
(SELECT     Account, SUM(Quantity) AS Quntity, Object_Id
FROM         (SELECT     cre_account AS Account, - SUM(Quantity) AS Quantity, Object_Id
                       FROM          dbo.Provodka
                       GROUP BY cre_account, Object_Id
                       UNION
                       SELECT     deb_account AS Account, SUM(Quantity) AS Quantity, Object_Id
                       FROM         dbo.Provodka AS Provodka_1
                       GROUP BY deb_account, Object_Id) AS drvTable
GROUP BY Account, Object_Id) AS v CROSS apply

                         (SELECT     TOP 1 *
                            FROM          dbo.Provodka g
                            WHERE      (g.deb_account = v.Account OR
                                                   g.cre_account = v.Account) AND g.Object_Id = v.Object_Id) cr
WHERE     v.Quantity > 0
END
11 мар 13, 14:06    [14035295]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
Приведите еще пример плана выполнения.
11 мар 13, 14:17    [14035379]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Glory
Member

Откуда:
Сообщений: 104760
test4me
незнаю что делать..помогите пожалуста советом и примером что сделать..

А что собственно хотите то сделать ?
11 мар 13, 14:19    [14035401]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
В подзапросе TOP 1 без ORDER BY - дальше можно не смотреть. Несерьёзно.

Но часто замена CROSS APPLY на старый добрый INNER JOIN со связкой снаружи подзапроса резко ускоряет выполнение.
Много раз приходилось так делать.
11 мар 13, 14:32    [14035543]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
С другой стороны ничего не известно - ни структура, ни индексы
11 мар 13, 14:33    [14035549]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
как вариант можно было бы
автор
(g.deb_account = v.Account OR
g.cre_account = v.Account)

разбить на два запроса через union all

и подумать
автор
SELECT     cre_account AS Account, - SUM(Quantity) AS Quantity, Object_Id
                       FROM          dbo.Provodka
                       GROUP BY cre_account, Object_Id
                       UNION
                       SELECT     deb_account AS Account, SUM(Quantity) AS Quantity, Object_Id
                       FROM         dbo.Provodka AS Provodka_1
                       GROUP BY deb_account, Object_Id

так ли нужен тут union а не достаточно ли union all

А так все гадание, без таблиц, индексов, планов
11 мар 13, 14:45    [14035658]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
Cпасибо всем за быстрый ответ! Извините, может задам не корректные вопрсы, с базами тесно никогда еще не сталкивался..но сейчас вот приходится...Попытаюсь сказать что за структура: Таблица Проводки где есть deb_account, cre_account, Quantity, Object_Id, и плюс остальные поля которые нужны как дополнительная информация...вычисления происходят следующим образом:
записи группируются по deb_account и Object_Id и отдельно группируем по cre_account, Quantity..где получаем в полях Quantity положительные суммы по дебету отдельно в первом запросе и суммы отрицательные по кредиту в последствии накладывая суммы в Quantity друг на друга в UNION получаем после группировки Аccount и Object_Id суммы которые уже вычислены и после этого к этим записям мне нужно прицепить все остальные дополнительные поля которые не участовали в вычислениях...вот что получилось у меня...может скажете как иначе может сделать тоже самое...но минута на все это слишком долго при 85000 записях нетакли?
11 мар 13, 14:59    [14035772]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
Не это хотели?
select * from (
   select deb_account Account,OBJECT_ID, sum(Quantity)Quantity from Provodka group by deb_account,OBJECT_ID
   union all
   select cre_account,OBJECT_ID, -sum(Quantity)Quantity from Provodka group by cre_account,OBJECT_ID
)u
join Provodka p on p.OBJECT_ID=u.OBJECT_ID
11 мар 13, 15:08    [14035841]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
Cygapb-007, нет в этом варианте пока хватило терпения до 4 минут...еще выполняется...((((
11 мар 13, 15:38    [14036068]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
есть какие нибудь идеи? остается сделать запрос где в группировку включить абсолютно все поля и те которые не участвуют в вычислениях?
11 мар 13, 15:42    [14036096]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Glory
Member

Откуда:
Сообщений: 104760
test4me
записи группируются по deb_account и Object_Id и отдельно группируем по cre_account, Quantity..где получаем в полях Quantity положительные суммы по дебету отдельно в первом запросе и суммы отрицательные по кредиту в последствии накладывая суммы в Quantity друг на друга в UNION получаем после группировки Аccount и Object_Id суммы которые уже вычислены и после этого к этим записям мне нужно прицепить все остальные дополнительные поля которые не участовали в вычислениях

Если из-за группировки записей становится меньше, то какой смысл в "к этим записям мне нужно прицепить все остальные дополнительные поля" ?
11 мар 13, 15:42    [14036099]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
Glory,

смысл таков есть таблица Х в нем поля А, Б, В, Г, Д, Е,....Я ... нужно получить сумму скажем 2х полей А и Б при группировке по полям Г и Д а остальные поля Е..Я прицепить к полученным записям естественно сравнив их по полю Г скажем....как это сделать?
11 мар 13, 15:55    [14036167]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
если группировать абсолютно по всем полям выполняется всего за 3 сек но зато получается результат не тот...тоесть в этом случае учитывается каждое поле...особенно если поле где есть ДАТА (там даты указаны в формате число меся год часы минуты и секунды) получается что каждая запись суммируется и по этому полю (по всем отдельно)...а мне нужны лишь 2 поля где вычисляется сумма а остальные нужно просто прицепить...непонимаю как это сделать..
11 мар 13, 16:07    [14036269]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Гость333
Member

Откуда:
Сообщений: 3683
test4me
есть таблица Х в нем поля А, Б, В, Г, Д, Е,....Я ... нужно получить сумму скажем 2х полей А и Б при группировке по полям Г и Д а остальные поля Е..Я прицепить к полученным записям естественно сравнив их по полю Г

Ничего не понял. Приведите какой-нибудь пример, иллюстрирующий "прицепление" полей Е..Я с учётом сравнения по полю Г.
11 мар 13, 16:10    [14036294]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
Гость333,

Представьте есть организация у которой есть несколько филиалов и все они ведут запись в одну и ту же таблицу тоесть отличаются только по полю Object_Id есть два вида записей в основном где происходит запись по ДЕБЕТУ и КРЕДИТУ...тоесть есть поле deb_account, cre_account сюда пишется код продукта а в поле Quantity пишется количество продукта в зависимости продался продукт или наоборот он пришел на склад...например если продукт пришел пишем:
Date deb_account cre_account Quantity Object_Id Name Razmer Color BarCode Adress Size
11.03.2013-12:33:45 00001 1610001 32 15 Деталь 1234 45 12 12300012 12 10

если продукт ушел тоесть реализовался то происходит запись:

Date deb_account cre_account Quantity Object_Id Name Razmer Color BarCode Adress Size
11.03.2013-13:33:45 11201 00001 11 15 Деталь 1234 45 12 12300012 12 10

мне нужно чтобы из этих записей получить:

Date deb_account cre_account Quantity Object_Id Name Razmer Color BarCode Adress Size
неважно 00001 неважно 32-11=21 15 Деталь 1234 45 12 12300012 12 10

и это конечно по каждому Object_Id и deb_account

я делаю группирвку по Object_Id , deb_account получаю сумму по полю +Quantity объединяю с группировкой по Object_Id , сre_account получаю сумму по полю -Quantity а поля Date,Name , Razmer ,Color , BarCode , Adress и Size нужно какимто образом прицепить к получившейся записи, чтобы в дальнейшем я мог использовать...Незнаю как смог объяснил...
11 мар 13, 16:58    [14036617]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Гость333
Member

Откуда:
Сообщений: 3683
test4me
Гость333,

Представьте есть организация у которой есть несколько филиалов и все они ведут запись в одну и ту же таблицу тоесть отличаются только по полю Object_Id есть два вида записей в основном где происходит запись по ДЕБЕТУ и КРЕДИТУ...тоесть есть поле deb_account, cre_account сюда пишется код продукта а в поле Quantity пишется количество продукта в зависимости продался продукт или наоборот он пришел на склад...например если продукт пришел пишем:
Date deb_account cre_account Quantity Object_Id Name Razmer Color BarCode Adress Size
11.03.2013-12:33:45 00001 1610001 32 15 Деталь 1234 45 12 12300012 12 10


если продукт ушел тоесть реализовался то происходит запись:

Date deb_account cre_account Quantity Object_Id Name Razmer Color BarCode Adress Size
11.03.2013-13:33:45 11201 00001 11 15 Деталь 1234 45 12 12300012 12 10


мне нужно чтобы из этих записей получить:

Date deb_account cre_account Quantity Object_Id Name Razmer Color BarCode Adress Size
неважно 00001 неважно 32-11=21 15 Деталь 1234 45 12 12300012 12 10


и это конечно по каждому Object_Id и deb_account

я делаю группирвку по Object_Id , deb_account получаю сумму по полю +Quantity объединяю с группировкой по Object_Id , сre_account получаю сумму по полю -Quantity а поля Date,Name , Razmer ,Color , BarCode , Adress и Size нужно какимто образом прицепить к получившейся записи, чтобы в дальнейшем я мог использовать...Незнаю как смог объяснил...

Группируйте также по полям Name, Razmer, Color, BarCode, Adress и Size. Я так понимаю, проблема в том, что дату надо учитывать с точностью до начала суток? Тогда группируйте по cast([Date] as date) (если у вас MSSQL 2008 и выше), либо по dateadd(day, datediff(day, '20000101', [Date]), '20000101').
11 мар 13, 17:10    [14036660]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
вообще лучше, если будет такая возможность, описание товара в отдельную таблицу вынести и оттуда вытаскивать уже после подсчета движения по счету в разрезе товара. Ну если совсем ничего не поделать и группировать не хочется по атрибутам товара, то можно
индексы создать по полям dbo.Provodka (deb_account,object_ID,DATE desc) include(Name, Razmer, Color, BarCode, Adress , Size)
и dbo.Provodka (cre_account,object_ID,DATE desc) include(Name, Razmer, Color, BarCode, Adress , Size) и соответственно не
SELECT     TOP 1 *
а
SELECT     TOP 1 Name, Razmer, Color, BarCode, Adress , Size
 FROM          dbo.Provodka g
                            WHERE      (g.deb_account = v.Account OR
                                                   g.cre_account = v.Account) AND g.Object_Id = v.Object_Id
order by DATE desc
11 мар 13, 17:27    [14036730]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
Спасибо всем за быстрые ответы!!!! Попробую сейчас все переделать...отпишусь
11 мар 13, 17:37    [14036770]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
Доброго времени суток! Попробовал разделить базу на 2 таблицы:
Таблица 1-я (Id_first, deb_account, cre_account, Quantity, Object_Id),
Таблица 2-я (Id, Date, Name, Razmer, Color, BarCode, Adress, Size, Id_first)
и дальше SELECT * FROM dbo.Provodka1 AS a INNER JOIN dbo.Provodka2 AS b ON a.Id_first = b.Id_first
все работает прекрсно...но потом вспомнил что мне нужно сначало в 1-й таблице получить сумму разниц по Quantity
группируя по Object_Id...как же мне в этом случае потом по Id_first связать эти 2 таблицы...чтото опять нето (((
19 мар 13, 01:39    [14065117]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
test4me,
ну так у вас в самом начале был запрос, вот его и используйте, только немного поменяйте. Через Cross Apply цепляем Provodka2 и группировку меняем на GROUP BY Account, Object_Id, Id_first . id_first ведь одинаковые для одинаковых object_id?
19 мар 13, 10:03    [14065685]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
да, Top 1 в подзапросе тоже, по всей видимости, не нужен уже
19 мар 13, 10:04    [14065693]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
Мистер Хенки
Приведите пример пожалуста? Спасибо
19 мар 13, 11:06    [14066020]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
Мистер Хенки,

автор
id_first ведь одинаковые для одинаковых object_id?

Нет..необязательно для одинаковых object_id одинаковые id_first, object_id это уникальный идентификатор объекта по которому должны группироваться все остальные...а id_first хотел использовать как уникальный идентификатор который одинаков в записях как в первой таблице так и для второй таблицы...для того чтобы по этому уникальному номеру прицепить записи из второй таблицы..
19 мар 13, 11:27    [14066156]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
test4me
Мистер Хенки,

автор
id_first ведь одинаковые для одинаковых object_id?

Нет..необязательно для одинаковых object_id одинаковые id_first, object_id это уникальный идентификатор объекта по которому должны группироваться все остальные...а id_first хотел использовать как уникальный идентификатор который одинаков в записях как в первой таблице так и для второй таблицы...для того чтобы по этому уникальному номеру прицепить записи из второй таблицы..

А, понял, я просто ошибся насчет вашей модели данных.
19 мар 13, 12:03    [14066398]     Ответить | Цитировать Сообщить модератору
 Re: CROSS apply работает медленно?  [new]
test4me
Member

Откуда:
Сообщений: 44
Мистер Хенки,

как думаете...есть какойто выход при таком положении...можно во вторую таблицу добавить поля что в первом Object_Id и Account так как они являются уникальными для обоих и связать их по этим 2 полям!?...
19 мар 13, 12:19    [14066511]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить