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

Откуда:
Сообщений: 9
Добрый день/вечер/ночь/утро!

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

Запрос довольно сложный, но в конце него стоит например:

and(fm like 'литвинова%') отобрано - 0 записей, если процентик убрать то записи находятся. Кто нибудь сталкивался с подобной проблемой?

Где можно покопать?

С уважением
SGKV



23 авг 05, 08:43    [1808757]     Ответить | Цитировать Сообщить модератору
 Re: не правильно отрабатывает select  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 34255
Блог
сравните планы выполнения запросов
23 авг 05, 08:56    [1808772]     Ответить | Цитировать Сообщить модератору
 Re: не правильно отрабатывает select  [new]
Брюлик
Member

Откуда:
Сообщений: 690
Можешь нам показать табличку с данными и твои селект, чтобы можно было протестировать?
23 авг 05, 08:58    [1808775]     Ответить | Цитировать Сообщить модератору
 Относительно тестирования запроса  [new]
L_Dorrit
Member

Откуда:
Сообщений: 56
Относительно показать табличку с данными: все не так просто. Там не одна табличка, их в запросе много. Если брать данные ТОЛЬКО из одной таблички и оставлять ТОЛЬКО это условие по LIKE, то разницы в выборках НЕТ. Разница есть только в том случае, когда все это работает в связке.

Разницы в планах исполнения тоже почти нет. План номер раз, без %:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|--Nested Loops(Left Semi Join, OUTER REFERENCES:([P].[Pn01]))
|--Index Seek(OBJECT:([MainBase].[dbo].[Person].[IX_Person_1] AS [P]), SEEK:([P].[Pn02] >= 'ЛИТВИНОВА' AND [P].[Pn02] <= 'ЛИТВИНОВА'), WHERE:(like([P].[Pn02], 'ЛИТВИНОВА', NULL)) ORDERED FORWARD)
|--Row Count Spool
|--Stream Aggregate(GROUP BY:([Rank1012]))
|--Nested Loops(Left Semi Join, OUTER REFERENCES:([A_Adres].[Adres02]))
|--Nested Loops(Inner Join, OUTER REFERENCES:([Link].[Link05]))
| |--Sort(ORDER BY:([Rank1012] ASC))
| | |--Rank
| | |--Index Seek(OBJECT:([MainBase].[dbo].[Link].[IX_Link_3]), SEEK:([Link].[Link04]=2 AND [Link].[Link01]=1 AND [Link].[Link02]=[P].[Pn01] AND [Link].[Link03]=1 OR [Link].[Link04]=2 AND [Link].[Link01]=1 AND [Link].[Link0
| |--Clustered Index Seek(OBJECT:([MainBase].[dbo].[A_Adres].[IX_A_Adres]), SEEK:([A_Adres].[Adres01]=[Link].[Link05]) ORDERED FORWARD)
|--Row Count Spool
|--Filter(WHERE:(like([A_Strit].[ST_NAME], 'чапаева%', NULL)))
|--Bookmark Lookup(BOOKMARK:([Bmk1007]), OBJECT:([MainBase].[dbo].[A_Strit]))
|--Nested Loops(Inner Join, OUTER REFERENCES:([A_Hous_IN].[Hous03]))
|--Index Seek(OBJECT:([MainBase].[dbo].[A_Hous_IN].[IX_A_Hous_IN_1]), SEEK:([A_Hous_IN].[Hous01]=[A_Adres].[Adres02]), WHERE:([A_Hous_IN].[Hous02]=1 AND ([A_Hous_IN].[Hous05]=NULL OR [A_Hous_IN].[Hous05]='')) ORDE
|--Index Seek(OBJECT:([MainBase].[dbo].[A_Strit].[PK_A_Strit]), SEEK:([A_Strit].[ST_ID]=[A_Hous_IN].[Hous03]) ORDERED FORWARD)

План номер два, с %:
StmtText
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|--Nested Loops(Left Semi Join, OUTER REFERENCES:([P].[Pn01]))
|--Index Seek(OBJECT:([MainBase].[dbo].[Person].[IX_Person_1] AS [P]), SEEK:([P].[Pn02] >= 'ЛИТВИНОВZЯ' AND [P].[Pn02] < 'ЛИТВИНОВб'), WHERE:(like([P].[Pn02], 'ЛИТВИНОВА%', NULL)) ORDERED FORWARD)
|--Row Count Spool
|--Sort(DISTINCT ORDER BY:([Rank1012] ASC))
|--Nested Loops(Left Semi Join, OUTER REFERENCES:([A_Adres].[Adres02]))
|--Nested Loops(Inner Join, OUTER REFERENCES:([Link].[Link05]))
| |--Rank
| | |--Index Seek(OBJECT:([MainBase].[dbo].[Link].[IX_Link_3]), SEEK:([Link].[Link04]=2 AND [Link].[Link01]=1 AND [Link].[Link02]=[P].[Pn01] AND [Link].[Link03]=1 OR [Link].[Link04]=2 AND [Link].[Link01]=1 AND [Link].[Link02]=[P
| |--Clustered Index Seek(OBJECT:([MainBase].[dbo].[A_Adres].[IX_A_Adres]), SEEK:([A_Adres].[Adres01]=[Link].[Link05]) ORDERED FORWARD)
|--Row Count Spool
|--Filter(WHERE:(like([A_Strit].[ST_NAME], 'чапаева%', NULL)))
|--Bookmark Lookup(BOOKMARK:([Bmk1007]), OBJECT:([MainBase].[dbo].[A_Strit]))
|--Nested Loops(Inner Join, OUTER REFERENCES:([A_Hous_IN].[Hous03]))
|--Index Seek(OBJECT:([MainBase].[dbo].[A_Hous_IN].[IX_A_Hous_IN_1]), SEEK:([A_Hous_IN].[Hous01]=[A_Adres].[Adres02]), WHERE:([A_Hous_IN].[Hous02]=1 AND ([A_Hous_IN].[Hous05]=NULL OR [A_Hous_IN].[Hous05]='')) ORDE
|--Index Seek(OBJECT:([MainBase].[dbo].[A_Strit].[PK_A_Strit]), SEEK:([A_Strit].[ST_ID]=[A_Hous_IN].[Hous03]) ORDERED FORWARD)

Разница при сравнении обнаружена в трех местах:
1) на условии, в которое преобразуется LIKE;
2) после --Row Count Spool - в одном случае Stream Aggregate(GROUP BY:, в другом Sort(DISTINCT ORDER BY
3) После --Nested Loops(Left Semi Join, OUTER REFERENCES:([A_Adres].[Adres02])) - в одном случае есть Sort(ORDER BY:([Rank1012] ASC)), в другом нет.
23 авг 05, 09:21    [1808811]     Ответить | Цитировать Сообщить модератору
 Сам запрос  [new]
L_Dorrit
Member

Откуда:
Сообщений: 56
Сам запрос выглядит примерно так.

SELECT
P.Pn01
, P.Pn02
, P.Pn03
, P.Pn04
FROM dbo.Person P
WHERE (P.Pn01 IN
(
SELECT link02 FROM mainbase.dbo.link
WHERE (link05 IN
(
SELECT adres01 FROM mainbase.dbo.a_adres
WHERE (adres02 IN
(
SELECT hous01 FROM mainbase.dbo.a_hous_in
WHERE (hous02 = 1)
AND (hous03 IN
(
SELECT st_id FROM mainbase.dbo.a_strit
WHERE (st_name LIKE 'чапаева%')
)) -- in, AND
AND(hous05 IS NULL OR hous05 = '')
) -- in
) -- where
) -- in
AND (link01 = 1)
AND (link03 IN (1,2))
AND (link04 = 2)) -- where
))
AND (P.Pn02 LIKE 'ЛИТВИНОВА')
23 авг 05, 09:22    [1808814]     Ответить | Цитировать Сообщить модератору
 Еще странности  [new]
L_Dorrit
Member

Откуда:
Сообщений: 56
Еще странности такие. При преобразовании запроса ЛЮБЫМ способом он отрабатывает одинаково вне зависимости от наличия или отсутствия %. То есть, например, при переписывании его с JOIN'ами все приходит в норму. При использовании алиаса для вложенного запроса - тоже. НО! По некоторым существенным причинам - заменить на JOIN очень нежелательно. Поэтому очень надо разобраться, ПОЧЕМУ НЕ РАБОТАЕТ КАК ЕСТЬ.

То есть вот это работает:
-------------------------
SELECT
Pn01
, Pn00
, Pn02
, Pn03
FROM dbo.Person P
JOIN mainbase.dbo.link L
ON (P.Pn01 = L.Link02)
JOIN mainbase.dbo.a_adres A
ON (A.Adres01 = L.Link05)
JOIN mainbase.dbo.a_hous_in H
ON (H.Hous01 = A.Adres02)
JOIN mainbase.dbo.a_strit S
ON (S.st_id = H.Hous03)
WHERE (st_name LIKE 'чапаева%')
AND (H.Hous05 = '' OR H.Hous05 IS NULL)
AND (L.Link01 = 1)
AND (L.Link03 IN (1,2))
AND (L.Link04 = 2)
AND (P.Pn02 LIKE 'ЛИТВИНОВА%')
-------------------------
И вот это тоже работает:
-------------------------
SELECT
P.Pn01
, P.Pn00
, P.Pn02
, P.Pn03
FROM dbo.Person P
, (
SELECT link02 FROM mainbase.dbo.link
WHERE (link05 IN
(
SELECT adres01 FROM mainbase.dbo.a_adres
WHERE (adres02 IN
(
SELECT hous01 FROM mainbase.dbo.a_hous_in
WHERE (hous02 = 1)
AND (hous03 IN
(
SELECT st_id FROM mainbase.dbo.a_strit
WHERE (st_name LIKE 'чапаева%')
)) -- in, AND
AND(hous05 IS NULL OR hous05 = '')
) -- in
) -- where
) -- in
AND (link01 = 1)
AND (link03 IN (1,2))
AND (link04 = 2)) -- where
) AS T1
WHERE (P.Pn02 LIKE 'ЛИТВИНОВА%')
AND (P.Pn01 = T1.Link02)
-------------------------
23 авг 05, 09:27    [1808841]     Ответить | Цитировать Сообщить модератору
 Re: не правильно отрабатывает select  [new]
Брюлик
Member

Откуда:
Сообщений: 690
Странно.
1) Попробуи перекомилировать запрос
2) Увеличь размер VARCHAR(n) по полю ,где ты ишешь Литвинову
23 авг 05, 09:33    [1808864]     Ответить | Цитировать Сообщить модератору
 Re: не правильно отрабатывает select  [new]
M0us
Member

Откуда: Moscow
Сообщений: 883
Не стоит так заморачиваться с кучей вложеных запросов.
рекомендую постараться обойтить JOIN-ами.
Это упростит запрос и Вы сами лучше станете понимать процесс выборки.

Селект-Монстр - это не есть показатель уровня мастерства, это есть шанс задуматься над его упрощением или упрощением структуры БД/ или введением дополнительных вьюх
23 авг 05, 10:19    [1809003]     Ответить | Цитировать Сообщить модератору
 Re: не правильно отрабатывает select  [new]
sgkv
Member

Откуда:
Сообщений: 9
M0us
Не стоит так заморачиваться с кучей вложеных запросов.
рекомендую постараться обойтить JOIN-ами.
Это упростит запрос и Вы сами лучше станете понимать процесс выборки.

Селект-Монстр - это не есть показатель уровня мастерства, это есть шанс задуматься над его упрощением или упрощением структуры БД/ или введением дополнительных вьюх


Запрос формируется динамически, параметров запроса около пятидесяти(47)
структура досталась в наследство и переделывать ее ... и тем более обсуждать уровень мастерства 8)))...

Кста, решилось:

...AND (ltrim(P.Pn02) LIKE 'ЛИТВИНОВА%')

и работает

...AND (rtrim(P.Pn02) LIKE 'ЛИТВИНОВА%')

и работает

...AND (lower(P.Pn02) LIKE 'ЛИТВИНОВА%')

и работает

...AND (upper(P.Pn02) LIKE 'ЛИТВИНОВА%')

и работает

Фантастика!!!
24 авг 05, 13:01    [1813102]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить