Переключение на Главную Страницу Страницы: 1 ... 4 5 [6]  ОтправитьПечать
Очень популярная тема (более 25 ответов) Можно ли ускорить процесс выборки (число прочтений - 13823 )
mozer
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 324
Местоположение: Пермь
Зарегистрирован: 14. Января 2011
Пол: Мужской
Re: Можно ли ускорить процесс выборки
Ответ #75 - 09. Сентября 2011 :: 09:28
Печать  
Вот что за запрос получился, но он выбирает все равно только элементы ... Где я накосячил ?

Код
Выбрать все
	|WITH Номенклатура_Иерархия(ID,Code,Descr,ParentID,IsFolder,SP85,SP94,Level) as (
	|SELECT
	|	СпрНоменкл.ID,
	|	СпрНоменкл.Code,
	|	СпрНоменкл.Descr,
	|	СпрНоменкл.ParentID,
	|	СпрНоменкл.IsFolder,
	|	СпрНоменкл.SP85,
	|	СпрНоменкл.SP94,
	|	1
	|FROM
	|	$Справочник.Номенклатура СпрНоменкл
	|WHERE
	|	СпрНоменкл.ParentID = $ПустойИД
	|UNION ALL
	|SELECT
	|	СпрН.ID,
	|	СпрН.Code,
	|	СпрН.Descr,
	|	СпрН.ParentID,
	|	СпрН.IsFolder,
	|	СпрН.SP85,
	|	СпрН.SP94,
	|	Level + 1
	|FROM
	|	$Справочник.Номенклатура СпрН
	|INNER JOIN
	|	Номенклатура_Иерархия СпрНИ ON СпрН.ParentID = СпрНИ.ID
	|)
	|
	|SELECT
	//|	СпрНом.ID,
	|	RTRIM(CAST(CAST(СпрНом.Code as INT) as CHAR)) Код,
	|	RTRIM(СпрНом.Descr) Наименование,
	//|	СпрНом.ParentID ИдГруппы,
	|	RTRIM(CAST(CAST(СпрНомГр.Code as INT) as CHAR)) КодРодителя,
	|	СпрНом.IsFolder Группа,
	|	RTRIM(СпрНом.SP85) Артикул,
	//|	СпрНом.SP94 Единица,
	|	RTRIM(СпрЕд.SP80) Штрихкод,
	|	$ПоследнееЗначение.Цены.Цена(СпрЦены.ID, :ВыбДата) Цена,
	|	Level Уровень,
	|	РегОстатки.КоличествоОстаток Остаток
	|FROM
	|	$РегистрОстатки.ОстаткиТМЦ(:ВыбДата~,,Фирма = :ВыбФирма AND Склад = :ВыбСклад,Номенклатура,Количество) as РегОстатки
	|LEFT JOIN
	|	Номенклатура_Иерархия СпрНом ON СпрНом.ID = РегОстатки.Номенклатура
	|LEFT JOIN
	|	$Справочник.Единицы СпрЕд ON СпрЕд.ID = СпрНом.SP94
	|LEFT JOIN
	|	$Справочник.Цены СпрЦены ON СпрЦены.ParentExt = СпрНом.ID
	|LEFT JOIN
	|	$Справочник.Номенклатура СпрНомГр ON СпрНомГр.ID = СпрНом.ID
	|
	|";
 



Понял! из рекурсивной таблицы выбираю только те что есть на остатке, а как бы так извернутся что бы он выбирал те что на остатке и все верхние?
  
Наверх
 
IP записан
 
mozer
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 324
Местоположение: Пермь
Зарегистрирован: 14. Января 2011
Пол: Мужской
Re: Можно ли ускорить процесс выборки
Ответ #76 - 09. Сентября 2011 :: 12:06
Печать  
Пока нашел только такое решение, но оно имеет недостатки
1. Работает конечно быстрей, но не намного раза 4 быстрей всего
2. Запрос обрабатывает всю номенклатуру до единой

Кто знает лучший вариант пишете. Буду рад любому предложению!

Код
Выбрать все
	|WITH Номенклатура_Иерархия(ID,Code,Descr,ParentID,IsFolder,SP85,SP94,Level) as (
	|SELECT
	|	СпрНоменкл.ID,
	|	СпрНоменкл.Code,
	|	СпрНоменкл.Descr,
	|	СпрНоменкл.ParentID,
	|	СпрНоменкл.IsFolder,
	|	СпрНоменкл.SP85,
	|	СпрНоменкл.SP94,
	|	1
	|FROM
	|	$Справочник.Номенклатура СпрНоменкл
	|WHERE
	|	СпрНоменкл.ParentID = $ПустойИД
	|UNION ALL
	|SELECT
	|	СпрН.ID,
	|	СпрН.Code,
	|	СпрН.Descr,
	|	СпрН.ParentID,
	|	СпрН.IsFolder,
	|	СпрН.SP85,
	|	СпрН.SP94,
	|	Level + 1
	|FROM
	|	$Справочник.Номенклатура СпрН
	|INNER JOIN
	|	Номенклатура_Иерархия СпрНИ ON СпрН.ParentID = СпрНИ.ID
	|)
	|
	|SELECT * FROM Номенклатура_Иерархия НомИерарх
	|LEFT JOIN
	|	$РегистрОстатки.ОстаткиТМЦ(:ВыбДата~,,Фирма = :ВыбФирма AND Склад = :ВыбСклад,Номенклатура,Количество) РегОстатки ON НомИерарх.ID = РегОстатки.Номенклатура AND НомИерарх.IsFolder = 2
	|";
 

  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Можно ли ускорить процесс выборки
Ответ #77 - 09. Сентября 2011 :: 13:28
Печать  
Заведи Товары в отдельной таблице
на этой таблице кластерный индекс  primary key из двух этих полей (Товар , Предок)

Товар , Предок :
Товар_1 -- Товар_1
Товар_1 -- Отец
Товар_1 -- Дед
.....
Товар_1 -- Предок_10

и так для всех товаров элементов.
услуги можно не включать.

И inner join к  этой таблице.

Конечно встает вопрос об актуальности  этой таблицы но товары достаточно редко тусуются по группам да и новые элементы создаются не часто.
  
Наверх
 
IP записан
 
mozer
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 324
Местоположение: Пермь
Зарегистрирован: 14. Января 2011
Пол: Мужской
Re: Можно ли ускорить процесс выборки
Ответ #78 - 12. Сентября 2011 :: 02:34
Печать  
Z1 писал(а) 09. Сентября 2011 :: 13:28:
Конечно встает вопрос об актуальности  этой таблицы но товары достаточно редко тусуются по группам да и новые элементы создаются не часто.

Новые товары могут быть созданы 3 раза в неделю.
Я для этих целей отчет прайс переписывал, что бы пользователь видел когда номенклатура создана была. Меняются уже существующие очень редко.
  
Наверх
 
IP записан
 
mozer
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 324
Местоположение: Пермь
Зарегистрирован: 14. Января 2011
Пол: Мужской
Re: Можно ли ускорить процесс выборки
Ответ #79 - 12. Сентября 2011 :: 06:10
Печать  
leshik писал(а) 08. Сентября 2011 :: 10:43:
Код
Выбрать все
...
ИтТз = Запрос.Выполнить("ИндексированнаяТаблица",ТекстЗапроса);

ВывестиСтрокиИтТз(ИтТз);
...


Процедура ВывестиСтрокиИтТз(ИсхТз)
 ИсхТз.ВыбратьСтроки();
 Пока ИсхТз.ПолучитьСтроку()=1 Цикл
   //Вывод первой группировки
   Если ПустоеЗначение(ИсхТз.тзПотомки)=0 Тогда
	  ВывестиСтрокиИтТз(ИсхТз.тзПотомки);
   КонецЕсли;
КонецПроцедуры 



Что то группировку не получается сделать ...
Делаю группировку, а тзПотомки не создается, значить группировка не создается или еще что то ?
  
Наверх
 
IP записан
 
mozer
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 324
Местоположение: Пермь
Зарегистрирован: 14. Января 2011
Пол: Мужской
Re: Можно ли ускорить процесс выборки
Ответ #80 - 13. Сентября 2011 :: 02:54
Печать  
И так чем все закончилось!
Запрос по рекурсии оказался хорош только для получения иерархии папок. В этом случае он работает быстро. Также при помощи рекурсивного запроса получил остатки хотя и без него можно обойтись (но пишу как есть переделывать не переделывал), в этом случае выборка также быстро происходит.
Дальше поступил следующим образом, выбрал иерархию папок, выбрал остатки все это в двух одинаковых по структуре таблицах.
Сортируем таблицу папок (иерархия папок) по уровню с убыванием (для того чтобы нижние уровни папок добавлялись первыми и в таблицу остатков с кодами своих родителей) добавление идет по условию кода родителя если код папки найден в столбце "КодРодителя" и не найден в столбце "Код", тогда добавим папку в таблицу остатков. В Результате получаем таблицу остатков с иерархией папок по остаткам, сортируем ее по уровню и признаку группы. Обрабатываем. Скорость в 9-10 раз быстрей если не пользоваться обычным запросом и стандартными функциями преобразования. Собственно все преобразования типов делаем в запросе  Подмигивание

Код
Выбрать все
сТекстПрямогоЗапросаОстатки = "
	|WITH Номенклатура_Иерархия(ID,Code,Descr,ParentID,IsFolder,SP85,SP94,Level) as (
	|SELECT
	|	СпрНоменкл.ID,
	|	СпрНоменкл.Code,
	|	СпрНоменкл.Descr,
	|	СпрНоменкл.ParentID,
	|	СпрНоменкл.IsFolder,
	|	СпрНоменкл.SP85,
	|	СпрНоменкл.SP94,
	|	1
	|FROM
	|	$Справочник.Номенклатура СпрНоменкл
	|WHERE
	|	СпрНоменкл.ParentID = $ПустойИД
	|UNION ALL
	|SELECT
	|	СпрН.ID,
	|	СпрН.Code,
	|	СпрН.Descr,
	|	СпрН.ParentID,
	|	СпрН.IsFolder,
	|	СпрН.SP85,
	|	СпрН.SP94,
	|	Level + 1
	|FROM
	|	$Справочник.Номенклатура СпрН
	|INNER JOIN
	|	Номенклатура_Иерархия СпрНИ ON СпрН.ParentID = СпрНИ.ID
	|)
	|
	|SELECT
	|	СпрНом.ID [Номенклатура $Справочник.Номенклатура],
	|	RTRIM(CAST(CAST(СпрНом.Code as INT) as CHAR)) Код,
	|	RTRIM(СпрНом.Descr) Наименование,
	|	СпрНом.ParentID ИдГруппы,
	|	RTRIM(CAST(CAST(СпрНомГр.Code as INT) as CHAR)) КодРодителя,
	|	СпрНом.IsFolder Группа,
	|	RTRIM(СпрНом.SP85) Артикул,
	|	RTRIM(СпрЕд.SP80) Штрихкод,
	|	Level Уровень,
	|	РегОстатки.КоличествоОстаток Остаток
	|FROM
	|	$РегистрОстатки.ОстаткиТМЦ(:ВыбДата~,,Фирма = :ВыбФирма AND Склад = :ВыбСклад,Номенклатура,Количество) as РегОстатки
	|LEFT JOIN
	|	Номенклатура_Иерархия СпрНом ON СпрНом.ID = РегОстатки.Номенклатура
	|LEFT JOIN
	|	$Справочник.Единицы СпрЕд ON СпрЕд.ID = СпрНом.SP94
	|LEFT JOIN
	|	$Справочник.Номенклатура СпрНомГр ON СпрНомГр.ID = СпрНом.ParentID
	|
	|";

Запрос выше можно и переделать, но не досуг пока.  :)


	сТекстПрямогоЗапросаИерархия = "
	|WITH Номенклатура_Иерархия(ID,Code,Descr,ParentID,IsFolder,SP85,SP94,Level) as (
	|SELECT
	|	СпрНоменкл.ID,
	|	СпрНоменкл.Code,
	|	СпрНоменкл.Descr,
	|	СпрНоменкл.ParentID,
	|	СпрНоменкл.IsFolder,
	|	СпрНоменкл.SP85,
	|	СпрНоменкл.SP94,
	|	1
	|FROM
	|	$Справочник.Номенклатура СпрНоменкл
	|WHERE
	|	СпрНоменкл.ParentID = $ПустойИД
	|UNION ALL
	|SELECT
	|	СпрН.ID,
	|	СпрН.Code,
	|	СпрН.Descr,
	|	СпрН.ParentID,
	|	СпрН.IsFolder,
	|	СпрН.SP85,
	|	СпрН.SP94,
	|	Level + 1
	|FROM
	|	$Справочник.Номенклатура СпрН
	|INNER JOIN
	|	Номенклатура_Иерархия СпрНИ ON СпрН.ParentID = СпрНИ.ID AND СпрН.IsFolder = 1
	|)
	|
	|SELECT
	|	НомИерарх.ID [Номенклатура $Справочник.Номенклатура],
	|	RTRIM(CAST(CAST(НомИерарх.Code as INT) as CHAR)) Код,
	|	RTRIM(НомИерарх.Descr) Наименование,
	|	НомИерарх.ParentID ИдГруппы,
	|	RTRIM(CAST(CAST(СпрНомГр.Code as INT) as CHAR)) КодРодителя,
	|	НомИерарх.IsFolder Группа,
	|	RTRIM(НомИерарх.SP85) Артикул,
	|	НомИерарх.SP94 Единица,
	|	RTRIM(СпрЕд.SP80) Штрихкод,
	|	Level Уровень,
	|	0 Остаток
	|FROM
	|Номенклатура_Иерархия НомИерарх
	|LEFT JOIN
	|	$Справочник.Единицы СпрЕд ON СпрЕд.ID = НомИерарх.SP94
	|LEFT JOIN
	|	$Справочник.Номенклатура СпрНомГр ON СпрНомГр.ID = НомИерарх.ParentID
	|";
 

  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1 ... 4 5 [6] 
ОтправитьПечать