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

Откуда: Ставропольский край
Сообщений: 12434
Здравствуйте.
Помогите разобраться в таком моменте:
Два сервера (MS SQL Server), две базы, две бд. В первой базе таблица с двумя столбцами соответствия ключей (a_id int, b_id varchar):

a_id b_id
1313 d9a10275-3451-4078-dddd-75c48bdbaf44:15808:10728
.
.
.

Второй сервер, через "Связанные серверы" имеет доступ к этой таблице.

Необходимо получить a_id по ключу из b_id.
Этот код выполняется на обоих серверах:
SELECT * FROM (SELECT a_id, b_id =
	(SELECT substring(cn, start, end_-37)
		FROM
		  (SELECT
			  charindex(':', p.b_id) + 1 as start,
			  charindex(':', p.b_id, charindex(':', p.b_id) + 1) - 1 as end_, p.b_id AS cn
		  WHERE len(p.b_id) > 10) 
		AS t)
FROM dbo.tbl_1 AS p)
AS tt
WHERE b_id = '15808'


А этот, только на первом:
SELECT b_id, a_id 
FROM (SELECT SUBSTRING(cn, start, end_ - 37) AS b_id, a_id from 
        (SELECT CHARINDEX(':', dbo.tbl_1.b_id) + 1 AS start, CHARINDEX(':', dbo.tbl_1.b_id, CHARINDEX(':', dbo.tbl_1.b_id) + 1) - 1 AS end_, 
     dbo.tbl_1.b_id AS cn, b_id
    FROM dbo.tbl_1
    WHERE (LEN(dbo.tbl_1.b_id) > 10)) as tt) as ttt
    WHERE b_id='15808'

При выполнении на втором выдаёт ошибку:
Функции LEFT или SUBSTRING передан недопустимый параметр длины.

Причём, проблема только в "WHERE b_id='15808'". Без условия, работает.
Почему? С чем это может быть связано?
Спасибо.
15 дек 16, 13:50    [20006952]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
связано с тем, что вычисление выражения substring(cn, start, end_-37) в плане может быть перемещено в самое неожиданное место. в частности, оно может вычисляться ДО проверки условия len(p.b_id) > 10. так что, полагаться на то, что оно отсечет строки, для которых в start, end_-37 получатся некорректные значения, увы, нельзя.
15 дек 16, 14:00    [20007006]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
daw
связано с тем, что вычисление выражения substring(cn, start, end_-37) в плане может быть перемещено в самое неожиданное место. в частности, оно может вычисляться ДО проверки условия len(p.b_id) > 10. так что, полагаться на то, что оно отсечет строки, для которых в start, end_-37 получатся некорректные значения, увы, нельзя.

а почему второй код выполняется на сервере, где физически находится таблица? получается там, всё корректно вычисляется, а на том, где связь нет?
Как лечить подобное?
15 дек 16, 14:09    [20007071]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31822
SNiL
а почему второй код выполняется на сервере, где физически находится таблица? получается там, всё корректно вычисляется, а на том, где связь нет?
Как лечить подобное?
Сервер строит план так, как считает нужным.
Может считать выражения до фильтрации, может после.
Вот если "до", то возникают такие ошибки.
Лечится это использованием CASE в выражениях.
SELECT CASE WHEN LEN(dbo.tbl_1.b_id) > 10 THEN CHARINDEX(':', dbo.tbl_1.b_id) + 1 END AS start
...
15 дек 16, 14:21    [20007152]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
> а почему второй код выполняется на сервере, где физически находится таблица? получается там, всё корректно вычисляется, а на том, где связь нет?

видимо, это к другому плану приводит

> Как лечить подобное?

надежнее всего - разбить запрос на части. да, получится переливка из одной времянки в другую.
иногда можно зафиксировать нужный план хинтами.
15 дек 16, 14:25    [20007200]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
alexeyvg
Может считать выражения до фильтрации, может после.

а принудительно только через case?
в принципе, len(p.b_id) > 10, не обязательно, можно убрать. тогда как заставить вычислять выражение до сортировки?
и ещё не понятно, первый код отрабатывается на обоих серверах без проблем и ошибок пока не замечено. почему для него план правильно строится?
15 дек 16, 14:33    [20007282]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
msLex
Member

Откуда:
Сообщений: 8856
SNiL
а принудительно только через case?

Да
SNiL
Первый код отрабатывается на обоих серверах без проблем и ошибок пока не замечено. почему для него план правильно строится?

Оба плана правильные, просто один из них "вскрывает" ошибку в вашем коде, а другой нет
15 дек 16, 14:56    [20007514]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
aleks2
Guest
SNiL
alexeyvg
Может считать выражения до фильтрации, может после.

а принудительно только через case?
в принципе, len(p.b_id) > 10, не обязательно, можно убрать. тогда как заставить вычислять выражение до сортировки?
и ещё не понятно, первый код отрабатывается на обоих серверах без проблем и ошибок пока не замечено. почему для него план правильно строится?


Может напрячь таки, эээ... мозг?

select * from dbo.tbl_1 WHERE b_id like '%:15808%:'
15 дек 16, 15:07    [20007592]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
aleks2
SNiL
пропущено...

а принудительно только через case?
в принципе, len(p.b_id) > 10, не обязательно, можно убрать. тогда как заставить вычислять выражение до сортировки?
и ещё не понятно, первый код отрабатывается на обоих серверах без проблем и ошибок пока не замечено. почему для него план правильно строится?


Может напрячь таки, эээ... мозг?

select * from dbo.tbl_1 WHERE b_id like '%:15808%:'

можете напрягать, разрешаю.
за что люблю айтишников, так за умение отвечать не конкретно по делу, а на отвлечённые темы. я же совсем про другое спрашиваю. не заметно?
15 дек 16, 15:19    [20007690]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
msLex
SNiL
Первый код отрабатывается на обоих серверах без проблем и ошибок пока не замечено. почему для него план правильно строится?

Оба плана правильные, просто один из них "вскрывает" ошибку в вашем коде, а другой нет

так а в чём ошибка то? коды, в принципе, одинаковые. и выполняются. только один ерипенится :)
15 дек 16, 15:22    [20007723]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
aleks2
Guest
SNiL
aleks2
пропущено...


Может напрячь таки, эээ... мозг?

select * from dbo.tbl_1 WHERE b_id like '%:15808%:'

можете напрягать, разрешаю.
за что люблю айтишников, так за умение отвечать не конкретно по делу, а на отвлечённые темы. я же совсем про другое спрашиваю. не заметно?


Учись писать запросы, так, чтобы глупых проблем не возникало.

ЗЫ. А то создадут себе трудности и героически их преодолевают.
15 дек 16, 15:26    [20007759]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37200
SNiL
msLex
пропущено...

Оба плана правильные, просто один из них "вскрывает" ошибку в вашем коде, а другой нет

так а в чём ошибка то? коды, в принципе, одинаковые. и выполняются. только один ерипенится :)
Ошибка в том, что код не написан так, чтобы не ломался на определенных данных в определенных условиях.
15 дек 16, 15:27    [20007764]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
aleks2
SNiL
пропущено...

можете напрягать, разрешаю.
за что люблю айтишников, так за умение отвечать не конкретно по делу, а на отвлечённые темы. я же совсем про другое спрашиваю. не заметно?


Учись писать запросы, так, чтобы глупых проблем не возникало.

ЗЫ. А то создадут себе трудности и героически их преодолевают.

ну это ты там, своим мааасковским программистам расскажи. сижу их поделие разбираю. от "крупнейшей российской it компании"...
зы. не, ну что действительно не понятно, что это часть (упрощённая) решения совсем другой, большой задачи?
15 дек 16, 15:35    [20007818]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
aleks2
Guest
SNiL
aleks2
пропущено...


Учись писать запросы, так, чтобы глупых проблем не возникало.

ЗЫ. А то создадут себе трудности и героически их преодолевают.

ну это ты там, своим мааасковским программистам расскажи. сижу их поделие разбираю. от "крупнейшей российской it компании"...
зы. не, ну что действительно не понятно, что это часть (упрощённая) решения совсем другой, большой задачи?


А чем ты отличаешься от "мааасковского программиста"?

ЗЫ. Если даже тривиальный iif/case не умеешь применять. И основных принципов выполнения запросов не знаешь.
15 дек 16, 15:43    [20007879]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
aleks2
SNiL
пропущено...

ну это ты там, своим мааасковским программистам расскажи. сижу их поделие разбираю. от "крупнейшей российской it компании"...
зы. не, ну что действительно не понятно, что это часть (упрощённая) решения совсем другой, большой задачи?


А чем ты отличаешься от "мааасковского программиста"?

ЗЫ. Если даже тривиальный iif/case не умеешь применять. И основных принципов выполнения запросов не знаешь.

тем что после "оптимизации" перестало сааавсем работать :)
15 дек 16, 15:44    [20007888]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
aleks2
SNiL
пропущено...

ну это ты там, своим мааасковским программистам расскажи. сижу их поделие разбираю. от "крупнейшей российской it компании"...
зы. не, ну что действительно не понятно, что это часть (упрощённая) решения совсем другой, большой задачи?


А чем ты отличаешься от "мааасковского программиста"?

ЗЫ. Если даже тривиальный iif/case не умеешь применять. И основных принципов выполнения запросов не знаешь.

тем что я воообще не программист :)) и не претендую.
15 дек 16, 16:50    [20008270]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
TaPaK
aleks2
пропущено...


А чем ты отличаешься от "мааасковского программиста"?

ЗЫ. Если даже тривиальный iif/case не умеешь применять. И основных принципов выполнения запросов не знаешь.

тем что после "оптимизации" перестало сааавсем работать :)

да нет, уважаемый. после "оптимизации" наоборот - работает. в отличии от...
15 дек 16, 16:50    [20008279]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
invm
Member

Откуда: Москва
Сообщений: 9687
SNiL,

Если "в лоб" и не думая, замените charindex(':', p.b_id) на nullif(charindex(':', p.b_id), 0) и charindex(':', p.b_id, charindex(':', p.b_id) + 1) nullif(charindex(':', p.b_id, charindex(':', p.b_id) + 1), 0)
15 дек 16, 17:17    [20008438]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
смотрю_тут
Member

Откуда:
Сообщений: 1368
ну сделайте простой дебагинг кода.
что передалось в SELECT substring(cn, start, end_-37) есть значения?
разложите по полочкам.
Второй вопрос два разные сервера, у меня одного такой вопрос, а версии select @@version серверов одинаковые?
15 дек 16, 17:50    [20008622]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
invm,

Спасибо.
Всем спасибо. Но у меня вопрос всёже не столько об оптимизации запроса, сколько хотелось бы понять, почему код "условно с ошибкой" на одном сервере выполняется, а получая егоже с другого, нет? Ну т.е. на будущее. Там же подобного кода - вагон. А на "родном" сервере он работает.
Да, "код не написан так, чтобы не ломался на определенных данных в определенных условиях.", но данные одни и теже. Получается, вроде как ошибка, а вроде как и нет. И "основной принцип выполнения запросов" мне, в данном случае, не понятен, да.
15 дек 16, 17:59    [20008684]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
SNiL,

dbcc freeproccache на родном сервере и вполне возможно вы начнёте развлекаться и на нём
15 дек 16, 18:01    [20008696]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
iljy
Member

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

SQL - декларативный язык, и сервер сам решает, как ему написанный запрос выполнять. И он может как сначала проверить условие WHERE, а потом вычислить выражение в SELECT (и тогда запрос выполняется), так и сначала вычислить выражение, а потом накладывать условие (тогда вы получаете ошибку). Оба варианта выполнения для сервера допустимы, он выбирает способ исходя из своих представлений об эффективности.

Чтобы этого избежать, надо использовать варианты с однозначной последовательностью вычислений. Вам дали два - case и nullif.
15 дек 16, 18:06    [20008727]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
смотрю_тут
Второй вопрос два разные сервера, у меня одного такой вопрос, а версии select @@version серверов одинаковые?

кстати, да, разные:
родной
Microsoft SQL Server 2008 R2 (SP3) - 10.50.6000.34 (X64) Aug 19 2014 12:21:34 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)

откуда линкуюсь
Microsoft SQL Server 2008 (SP1) - 10.0.2573.0 (X64) Feb 4 2011 11:27:06 Copyright (c) 1988-2008 Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)

Хотя, меня уверяли в обратном :)) не проверял, раньше.
15 дек 16, 18:12    [20008752]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
TaPaK
SNiL,

dbcc freeproccache на родном сервере и вполне возможно вы начнёте развлекаться и на нём

у меня очень сильно порезаны права. я практически "партизаню" :))
15 дек 16, 18:15    [20008767]     Ответить | Цитировать Сообщить модератору
 Re: В чём принципиальное отличие запросов?  [new]
SNiL
Member

Откуда: Ставропольский край
Сообщений: 12434
iljy
SNiL,

SQL - декларативный язык, и сервер сам решает, как ему написанный запрос выполнять. И он может как сначала проверить условие WHERE, а потом вычислить выражение в SELECT (и тогда запрос выполняется), так и сначала вычислить выражение, а потом накладывать условие (тогда вы получаете ошибку). Оба варианта выполнения для сервера допустимы, он выбирает способ исходя из своих представлений об эффективности.

Чтобы этого избежать, надо использовать варианты с однозначной последовательностью вычислений. Вам дали два - case и nullif.

спасибо. вот это "сам решает" мне и не нравиться. чего он, получая тот же самый код от другого сервера (я правильно понимаю, ему так же "select...." передаётся?) свои представления об эффективности меняет, зараза? :)
в целом понятно - надо тщательнее относиться. case и nullif в данном случае помагают, да.
15 дек 16, 18:23    [20008808]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить