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

Откуда: Ростов- на- Дону
Сообщений: 564
Имею запрос

select * from book_bo --view
where docid in
(select docid from library2.dbo.book__Doc where docid in
(select docid FROM LIBRARY2.dbo.book_01003X where itemid in
(SELECT ItemID FROM LIBRARY2.dbo.book_01003 where item like '%петров%')))

это выдает внутренний запрос

docid
-------
3167
5868
8636
3945
1205
...
но, как показывает план, 98% идет на перебор сложного представления book_bo, содержащего функции.

Всего строк в таблице , например, 20000,а выбирается порядка 100-200!
Помогите плиз вывернуть наоборот запрос, чувствую, что можно сделать, но не получается пока!
28 дек 13, 15:44    [15359000]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
sdet
Member

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

Представьте структуры таблиц, что хотите получить. Или вам view надо оптимизировать?
28 дек 13, 16:21    [15359068]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
sdet,

взгляд
select
--top 100
--row_number()over(order by current_timestamp) N,
docid,
libra1.dbo.gethead(doc)
+libra1.dbo.GetSubField(doc,'200a') + ' '
+libra1.dbo.GetSubFldLR(doc,'[',']','200b') + ': '
+libra1.dbo.GetSubField(doc,'200e') + '/'
+libra1.dbo.GetSubFld(doc,'200f','.- ') +
+libra1.dbo.GetSubFld(doc,'200g','.- ') +
+libra1.dbo.GetSubFld(doc,'205a','- ') +
+libra1.dbo.GetSubField(doc,'210a') + ': '
+libra1.dbo.GetSubField(doc,'210c') + ', '
+libra1.dbo.GetSubField(doc,'210d') + '. '
+libra1.dbo.GetSubField(doc,'215a') + ' '
+libra1.dbo.GetSubFldLR(doc,'(',').','225a') +'- ISBN '
+libra1.dbo.GetSubField(doc,'010a') + ': '
+libra1.dbo.GetSubField(doc,'010d')
as BO,

libra1.dbo.GetAs ('book', docid) [AS],
libra1.dbo.GetSigla ('book', docid) [Sigla]

from library2.dbo.book__doc where (libra1.dbo.islinkbook(docid) =0)

мне оптимизировать не удастся, но надо сделать так, чтобы он применялся не к всей таблице,
но к выборке по ключевому полю из нее, а это намного меньше.
структуры таблиц вложенной части простые, но от них надо отвлечься и всю вложенную часть представить как главную,
а с взглядом как- то соединить.
28 дек 13, 16:36    [15359096]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
topdon,

ключевое поле здесь docid,
все работает правильно, только надо наоборот.
28 дек 13, 16:45    [15359111]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
sdet
Member

Откуда:
Сообщений: 463
topdon,
Не совсем понятно. Вас беспокоит что where вне view, а не внутри?
28 дек 13, 17:04    [15359149]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
topdon
все работает правильно, только надо наоборот.
Чтобы работало неправильно?
28 дек 13, 17:32    [15359218]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
topdon,

Покажите, пожалуйста, план запроса, код функции dbo.GetSubField и желательно скрипты таблиц и тестовые данные.
28 дек 13, 17:36    [15359231]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
Ruuu,

select row_number()over(order by current_timestamp) N, * from book_bo where docid in
(select docid from library2.dbo.book__Doc where docid in
(select docid FROM LIBRARY2.dbo.book_01003X where itemid in
(SELECT ItemID FROM LIBRARY2.dbo.book_01003 where item like '%уш%')))

это реальный запрос. Его результат урезанный

1 8566 Латинско-русский словарь [Текст]: /[авт.-сост. К. А. Тананушко].- Минск: Харвест, 2008. 1344 с. - ISBN 978-
2 8649 Муштук, Орест Захарович. Политология [Текст]: /О. З. Муштук.- 2-е изд., перераб. и доп.- М.: МФПА, 2011. RU (RU).- ISBN RU:

в прилагаемом файле план. Он сейчас другой, чем был ранее. Было 98% на 2%. 98- просмотр взгляда.

К сообщению приложен файл (1.csv - 43Kb) cкачать
28 дек 13, 17:57    [15359295]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
topdon,
но все равно просмотр таблицы 34 %.
28 дек 13, 18:01    [15359315]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
topdon,
у меня в основной таблице библиотека,
в паре вспомогательных значения поля и ключи записей.
из них я например выбираю 15, для которых я должен выдать библиографическое описание.
28 дек 13, 18:06    [15359332]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
sdet,
я бы хотел, чтобы сначала шло нахождение записей из внешних индексных таблиц (нижние селекты),
а потом подключался взгляд с БО.
28 дек 13, 18:09    [15359341]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Первоначальный запрос тоже надо изменить.
SELECT	V.*	-- 	Все колонки, а нужны ли все? Ибо для их вычисления возможно запускаются всякие ненужные функции
-- SELECT V.DocID
FROM	LIBRARY2.dbo.book_01003		B
JOIN	LIBRARY2.dbo.book_01003X	X ON X.ItemID	= B.ItemID
JOIN	         dbo.book_bo		V ON V.DocID	= X.DocID	--view
WHERE	B.item	LIKE '%петров%'
--AND	Exists(SELECT * FROM LIBRARY2.dbo.book__Doc D WHERE D.DocID = X.DocID)	-- Не очень понятна роль этого условия, может убрать?
После просмотра вью, оказалось понятно.
Совершенно не нужно было связывать повторно таблицу book__Doc.

1. Писать имя базы в названиях объектах самой базы не нужно.
2. Усвойте JOIN, наконец
3. Скалярными функция старайтесь не пользоваться. Желательно никогда.
Row_Number()Over(ORDER BY GetDate()) да ещё и в представлении?! Это такая шутка?

Вам придётся переписать все функции или на параметризованные представления, или просто переписать прямо в коде представления.
(dbo.gethead, dbo.GetSubField, dbo.GetSubFldLR, dbo.GetSubFld, dbo.GetAs, dbo.GetSigla, dbo.islinkbook)

+ VIEW dbo.book_bo
CREATE VIEW [dbo].[book_bo] AS
SELECT	D.DocID
,	libra1.dbo.gethead	(D.Doc)
+	libra1.dbo.GetSubField	(D.Doc,'200a') + ' '
+	libra1.dbo.GetSubFldLR	(D.Doc,'[',']','200b') + ': '
+	libra1.dbo.GetSubField	(D.Doc,'200e') + '/'
+	libra1.dbo.GetSubFld	(D.Doc,'200f','.- ') +
+	libra1.dbo.GetSubFld	(D.Doc,'200g','.- ') +
+	libra1.dbo.GetSubFld	(D.Doc,'205a','- ') +
+	libra1.dbo.GetSubField	(D.Doc,'210a') + ': '
+	libra1.dbo.GetSubField	(D.Doc,'210c') + ', '
+	libra1.dbo.GetSubField	(D.Doc,'210d') + '. '
+	libra1.dbo.GetSubField	(D.Doc,'215a') + ' '
+	libra1.dbo.GetSubFldLR	(D.Doc,'(',').','225a') +'- ISBN '
+	libra1.dbo.GetSubField	(D.Doc,'010a') + ': '
+	libra1.dbo.GetSubField	(D.Doc,'010d')		AS BO
,	libra1.dbo.GetAs 	('book', D.DocID)	AS [AS]
,	libra1.dbo.GetSigla	('book', D.DocID)	AS [Sigla]
FROM	library2.dbo.book__doc	D
WHERE	libra1.dbo.islinkbook(D.DocID) = 0
islinkbook - фильтр по скалярке приводит к скану всех данных, индекс явно не будет задействован.
Но я боюсь, судя по "качеству" кода, что тут вообще нет даже ключей, таблицы голые кучи.
Автору надо просто нанять проффессионала.
28 дек 13, 18:10    [15359345]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
sdet
Member

Откуда:
Сообщений: 463
topdon
sdet,
я бы хотел, чтобы сначала шло нахождение записей из внешних индексных таблиц (нижние селекты),
а потом подключался взгляд с БО.


where item like '%петров%' индекс не будет использоваться
28 дек 13, 18:13    [15359351]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
Mnior,
ребята, таблицы эти не мои, я в них с трудом разбираюсь.
Это не совсем работающая автоматизированная библиотека.
28 дек 13, 18:15    [15359355]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Mnior
2. Усвойте JOIN, наконец
Это самая главная проблема, что привело к появлению сего детища.
И обожания оператора "IN" и любвеобилие тормозных скалярок.
28 дек 13, 18:16    [15359359]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
 select row_number()over(order by current_timestamp) N, *
from book_bo
where docid in 
  (select docid
   from library2.dbo.book__Doc
   where docid in 
      (select docid
       FROM LIBRARY2.dbo.book_01003X
       where itemid in 
         (SELECT ItemID
          FROM LIBRARY2.dbo.book_01003
          where item like '%уш%')))

Ну так с like '%уш%' можете забыть про поиск по индексу, плюс этот огород из IN и подзапросов. Что за у вас таблицы book__Doc, book_01003X, book_01003?
28 дек 13, 18:22    [15359376]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
sdet,
он у меня уже использован. Вот смотрите

шаг 1-2-3
-------------
select docid from library2.dbo.book__Doc where docid in
(select docid FROM LIBRARY2.dbo.book_01003X where itemid in
(SELECT ItemID FROM LIBRARY2.dbo.book_01003 where item like '%хубаев%'))

запрос выполнен 0 сек.

docid
-------
1785
1678
4567
.......

19 строк.

а теперь для них надо применить связь с представлением. Да, я не профессионал в этом вопросе, но система работает все же,
правда вижу, что медленно. поэтому и обратился, но ...
28 дек 13, 18:26    [15359383]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
sdet
where item like '%петров%' индекс не будет использоваться
Да и вообще "библиотека" - автоматически приводит к мысли полнотекстового поиска.
topdon
ребята, таблицы эти не мои
Угу, ты просто разместил объяву. Отмазка №3. Старо как мир.

Чего вы от нас тогда хотите? Технические советы есть, как вы будете их применять - это ваше дело.

Это что за библиотека? Что за организация? Может туда нам волонтёрами устроится, нормально всё запрограмячить, а то это BSDM какой-то.
28 дек 13, 18:27    [15359385]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Ruuu
плюс этот огород из IN и подзапросов
Я же переписал его запрос уже! 15359345
Имхо, аффтар наверно и сам не знает что каждая табла означает.
28 дек 13, 18:29    [15359392]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
Mnior
Ruuu
плюс этот огород из IN и подзапросов
Я же переписал его запрос уже! 15359345
Имхо, аффтар наверно и сам не знает что каждая табла означает.
Я пока писал не видел ваше сообщение, иначе не стал бы своё опубликовывать. Готов подписаться под каждым вашим словом :)
28 дек 13, 18:34    [15359402]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
Ruuu,
не поняли.
Эти 2 таблиц у разработчиков (которых невозможно достать) играли роль индексных,
например

itemid item
----------------
2312 кушак
.......
2345 Пушков
.........


Itemid Docid
------------------
2345 4532
2312 1678
.......

этот поиск идет мгновенно, несмотря на like!
28 дек 13, 18:34    [15359403]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
Mnior
sdet
where item like '%петров%' индекс не будет использоваться
Да и вообще "библиотека" - автоматически приводит к мысли полнотекстового поиска.
topdon
ребята, таблицы эти не мои
Угу, ты просто разместил объяву. Отмазка №3. Старо как мир.

Чего вы от нас тогда хотите? Технические советы есть, как вы будете их применять - это ваше дело.

Это что за библиотека? Что за организация? Может туда нам волонтёрами устроится, нормально всё запрограмячить, а то это BSDM какой-то.


Извините, если Вас это так расстроило. Я не ожидал такой реакции.
28 дек 13, 18:40    [15359417]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
topdon
этот поиск идет мгновенно, несмотря на like!
1. То что он выдаёт первые строки сразу же - не означает что нет полного скана. И даже если выдаёт быстро - то 20000 - это просто пыль, по современным меркам.

2. Вам дали советы и даже переписали кое что.
Что вам ещё надо?
Если хотите помощи как переписать функции (вставить их код в представление), т.е. избавится от вызова скалярок.
То вам как минимум надо выложить их код.

Мы не предлагали изменять функции, т.е. писать новые и удалять старые, и тем более не предлагали менять базовые таблицы.
Вы просто должны создать новые (или просто написать "большой" запрос).
А то что я просто комментирую ситуацию, её реалии, это не должно было вас ставить в позицию "отбивающегося".
Репутацию тут вы не зарабатываете, мы все просто решаем проблемы, расслабьтесь уже наконец.
28 дек 13, 18:51    [15359462]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
Mnior,

Прошу прощения, если что- то не так сказал Расслабиться пока не удается, т.к. все это надо еще на сервере опубликовать.
Но это так, к слову.

Вот я взял Ваш запрос

select v.*
FROM LIBRARY2.dbo.book_01003 B
JOIN LIBRARY2.dbo.book_01003X X ON X.ItemID = B.ItemID
JOIN libra1.dbo.book_bo V ON V.DocID = X.DocID --view
WHERE B.item LIKE '%петров%'


он дал 29 строк 5 сек.

а мой старый, который я считал неправильным

select * from libra1.dbo.book_bo where docid in
(select docid from library2.dbo.book__Doc where docid in
(select docid FROM LIBRARY2.dbo.book_01003X where itemid in
(SELECT ItemID FROM LIBRARY2.dbo.book_01003 where item like '%Петров%')))

тот же р-тат, но 4 сек.

Вообще у меня некоторые запросы сек. по 30 висят. То что Вы писали про функции, я еще не обдумал.
Я их писал прямо с листа имея старую книжку хендерсона. Почему их нежелательно применять?
28 дек 13, 19:02    [15359502]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вывернуть наизнанку запрос!  [new]
topdon
Member

Откуда: Ростов- на- Дону
Сообщений: 564
Mnior
topdon
этот поиск идет мгновенно, несмотря на like!
1. То что он выдаёт первые строки сразу же - не означает что нет полного скана. И даже если выдаёт быстро - то 20000 - это просто пыль, по современным меркам.

2. Вам дали советы и даже переписали кое что.
Что вам ещё надо?
Если хотите помощи как переписать функции (вставить их код в представление), т.е. избавится от вызова скалярок.
То вам как минимум надо выложить их код.

Мы не предлагали изменять функции, т.е. писать новые и удалять старые, и тем более не предлагали менять базовые таблицы.
Вы просто должны создать новые (или просто написать "большой" запрос).
А то что я просто комментирую ситуацию, её реалии, это не должно было вас ставить в позицию "отбивающегося".
Репутацию тут вы не зарабатываете, мы все просто решаем проблемы, расслабьтесь уже наконец.


вот текст типичной функции,

ALTER FUNCTION [dbo].[GetSubField] (@str varchar(5000), @ff char(4))
RETURNS varchar(500)

AS
BEGIN
DECLARE
@i integer,
@f char(3),
@sf char(1),
@fld varchar(700),
@len integer,
@end integer,
@start integer,
@tmp varchar(500),
@ret varchar(500);

set @f = substring(@ff,1,3);
set @sf = substring(@ff,4,1);
set @fld = libra1.dbo.getfield(@str, @f);

set @start = patindex('%'+char(31)+@sf+'%', @fld);
--set @tmp = substring (@fld,@start, 500)

set @end = 0;

if @start <> 0 begin
set @end = patindex('%'+char(31)+'%', substring(@fld, @start+2, len(@fld)-@start-2));
if @end = 0 set @ret = substring(@fld, @start+2, len(@fld)-@start-1)
else set @ret = substring(@fld, @start+2, @end-1)
end
--if @ret='' set @ret = ' '
return isnull(@ret,'');

END;

Может и не оптимальна, но работает. Эти функции нужны чтобы выуживать поля из большого поля блоб,
в котором содержится поля описания книги.
28 дек 13, 19:10    [15359522]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить