powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Табличные подсказки, вычисляемое поле
18 сообщений из 18, страница 1 из 1
Табличные подсказки, вычисляемое поле
    #39189790
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть 2 таблицы:
Resources(ресурсы, на тестовой БД ~12 000 записей, в боевой ~ 30M) и
ResourceExtParams (дополнительные параметры, пока практически пустая)

Есть задача по добавлению/изменению дополнительных параметров ресурсов с определенным значением поля Resources.HashCode - хранимого вычисляемого поля (добавил только что)
Код: sql
1.
ALTER TABLE [dbo].[Resources] ADD [HashCode] AS (CHECKSUM(ISNULL(Name,'')+ ' ' + ISNULL(Code,'') + ' ' + ISNULL(UnitName,'')+ ' ' + CAST([Type] as NVARCHAR(10)))) PERSISTED NOT NULL


с построенным индексом
Код: sql
1.
2.
3.
4.
5.
6.
CREATE NONCLUSTERED INDEX [IX_HashCode] ON [dbo].[Resources] 
(
	[HashCode] ASC
)
INCLUDE ( [Id])
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 85) ON [PRIMARY]


Индекс включает поле Id, т.к. кластерный индекс построен по другому полю.
Была создана нехитрая хранимка
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE PROCEDURE [dbo].[UpdateResourceSupplierType]
	@NewSupplierTypeId TINYINT,
	@HashCode int
AS
BEGIN
	SET NOCOUNT ON	
	
	MERGE INTO dbo.ResourceExtParams
	USING  (select Id from dbo.Resources
			where HashCode = @HashCode) r
			on (r.Id = ResourceId)
	when matched then
		UPDATE  SET SupplierTypeId = @NewSupplierTypeId			
	when not matched by target then
		insert (ResourceId, SupplierTypeId) 
		values (r.Id, @NewSupplierTypeId);	
END


Обратил внимание, что при вызове
Код: sql
1.
exec UpdateResourceSupplierType 5,-1157169989


который должен изменить 4 записи в ResourceExtParams и 1 добавить, вместо поиска по IX_HashCode идет сканирование кластерного индекса Resources ( план1 в приложении), причем из него кроме Id зачем-то извлекаются все составляющие поля HashCode, но не оно само.

Попробовал добавить подсказку
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE PROCEDURE [dbo].[UpdateResourceSupplierType]
	@NewSupplierTypeId TINYINT,
	@HashCode int
AS
BEGIN
	SET NOCOUNT ON	
	
	MERGE INTO dbo.ResourceExtParams
	USING  (select Id from dbo.Resources WITH (INDEX(IX_HashCode))
			where HashCode = @HashCode) r
			on (r.Id = ResourceId)
	when matched then
		UPDATE  SET SupplierTypeId = @NewSupplierTypeId			
	when not matched by target then
		insert (ResourceId, SupplierTypeId) 
		values (r.Id, @NewSupplierTypeId);	
END


Выдал сообщение об ошибке
Код: sql
1.
Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET FORCEPLAN.


Что удивительно, т.к запуск
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	declare @NewSupplierTypeId int = 6,
			@HashCode int = -1157169989
	MERGE INTO dbo.ResourceExtParams
	USING  (select Id from dbo.Resources WITH (INDEX(IX_HashCode))
			where HashCode = @HashCode) r
			on (r.Id = ResourceId)
	when matched then
		UPDATE  SET SupplierTypeId = @NewSupplierTypeId			
	when not matched by target then
		insert (ResourceId, SupplierTypeId) 
		values (r.Id, @NewSupplierTypeId);


прекрасно отрабатывает с желанным планом ( план с подсказками в приложении)

Версия сервера
Код: sql
1.
2.
3.
4.
Microsoft SQL Server 2008 R2 (SP3) - 10.50.6000.34 (X64) 
	Aug 19 2014 12:21:34 
	Copyright (c) Microsoft Corporation
	Standard Edition (64-bit) on Windows NT 6.3 <X64> (Build 10586: )



1. Почему не работают подсказки в ХП?
2. Почему такой странный план без них(надо бы попробовать перестроить кластерный индекс CIX_PositionId)?
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39189827
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2. Перестроение CIX_PositionId ничего не измменило
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39189843
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шамиль Фаридович,

хинт может не работать в силу особенностей настройки базы, вида индекса. Т.е. если индекс принципиально не может быть использован, получим такую ошибку.
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39189847
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хинт выдает ошибку только при использовании его внутри ХП, если запустить запрос с использованием этого хинта то все прекрасно отрабатывает. как показано выше.
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39189869
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шамиль Фаридович,

в таком случае SET настройки в консоли отличаются от тех, которые были использованы при создании процедуры.
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39190099
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов,

а какая опция запрещает/разрешает использование хинтов в ХП?
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39190145
sergeimv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39190149
sergeimv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
+ попробуйте переопределить параметр @HashCode внутри процедуры
Код: sql
1.
declare @pHashCode int = @HashCode

и уже в запросе использовать его.
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39195179
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sergeimv,
познавательная статейка, но к сожалению
sergeimv+ попробуйте переопределить параметр @HashCode внутри процедуры
Код: sql
1.
declare @pHashCode int = @HashCode

и уже в запросе использовать его.
не решает моей проблемы - выскакивает все та же ошибка.
Видимо, Executor упорно пытается подсчитать значение вычисляемого поле вместо того, чтобы взять его сохраненное значение.
И делает он это только при вызове ХП, запущенный в студии запрос отрабатывает без проблем .
Что нужно дописать в ХП, чтобы она тоже работала?
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39195195
o-o
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
o-o
Гость
вот тут SQL Server doesn't use index in stored procedure
мужик с таким же боролся,
ему уйму советов дали, но ничего не помогло
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39195247
Фотография daw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шамиль ФаридовичВладислав Колосов,

а какая опция запрещает/разрешает использование хинтов в ХП?

использование хинтов - никакая. а вот индексы на вычисляемых столбцах могут использоваться только при определенных set-ах.

[quot BOL]
When you are creating and manipulating indexes on computed columns or indexed views, the SET options ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, ANSI_NULLS, ANSI_PADDING, and ANSI_WARNINGS must be set to ON. The option NUMERIC_ROUNDABORT must be set to OFF.
[quot]
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39195254
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
o-o,
улыбнуло) Правда описанный в топе пример у меня работает, возможно его пофиксили в каком-нить сервис-паке.

daw,
в точку! у меня при создании ХП было явно прописано
Код: sql
1.
SET ANSI_NULLS OFF


Даже не знаю зачем.

Спасибо!
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39195273
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, после проставления опций
dawWhen you are creating and manipulating indexes on computed columns or indexed views, the SET options ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, ANSI_NULLS, ANSI_PADDING, and ANSI_WARNINGS must be set to ON. The option NUMERIC_ROUNDABORT must be set to OFF.

сама собой решилась вторая проблема
Шамиль Фаридович2. Почему такой странный план без них
То есть теперь без хинтов используется IX_HashCode.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Табличные подсказки, вычисляемое поле
    #39758717
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовШамиль Фаридович,

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

в Оракле - если хинт не применим или не нравится оптимизатору, и фиг с ним, никакая ошибка не валится

Есть ли такой режим в MSSQL?

Ситуация:
есть табличная функция
внутри запрос -- несколько таблиц, юнионы, подзапросы, джойны, with, несколько or'ов
идет выбор или по диапазону одной даты, или по диапазону другой даты, все это размножается на or'ы других параметров
Вынес поиск id в with, добавил inner merge join, работает в разы быстрее
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
 ALTER FUNCTION [dbo].[get_tmp]
(
    @p_date_from    datetime,
    @p_date_to      datetime,
    @p_load_tasks   int, -- загружать ли подчиненные задачи
    @p_pocopy       int,
    -- where type
    -- 0 - по дате закрытия
    -- 1 - по дате создания
    -- 2 - по дате закрытия или дате SLA для просроченных за исключением отмененных
    @p_where_type   int,
    @p_folder       nvarchar(100) = N'М'
)

RETURNS TABLE AS RETURN
(

with ids as
(
    select INCIDENT_ID id
      from incidentsm1 obr
     where obr.CLOSE_TIME between cast(@p_date_from AT TIME ZONE 'FLE Standard Time' AT TIME ZONE 'UTC' as datetime)
                              and cast(@p_date_to   AT TIME ZONE 'FLE Standard Time' AT TIME ZONE 'UTC' as datetime)
           and @p_where_type in (0, 2)
           and not (isnull(obr.HPC_CANCELLED_BY_USER, '') = 't' and @p_where_type in (2))
           and (isnull(obr.folder, N'М') = @p_folder or isnull(@p_folder, '') = '' and isnull(obr.folder, N'М') <> N'H')
    union
    select INCIDENT_ID id
      from incidentsm1 obr
     where obr.open_TIME between cast(@p_date_from AT TIME ZONE 'FLE Standard Time' AT TIME ZONE 'UTC' as datetime)
                             and cast(@p_date_to   AT TIME ZONE 'FLE Standard Time' AT TIME ZONE 'UTC' as datetime)
           and @p_where_type = 1
           and (isnull(obr.folder, N'М') = @p_folder or isnull(@p_folder, '') = '' and isnull(obr.folder, N'М') <> N'H')
    union
    select INCIDENT_ID id
      from incidentsm1 obr
     where obr.HPC_NEXT_BREACH  between cast(@p_date_from AT TIME ZONE 'FLE Standard Time' AT TIME ZONE 'UTC' as datetime)
                                    and cast(@p_date_to   AT TIME ZONE 'FLE Standard Time' AT TIME ZONE 'UTC' as datetime)
            and @p_where_type in (2)
            and obr.sla_breach = 't'
            and (obr.CLOSE_TIME is null or obr.CLOSE_TIME between @p_date_from and @p_date_to)
           and (isnull(obr.folder, N'М') = @p_folder or isnull(@p_folder, '') = '' and isnull(obr.folder, N'М') <> N'H')
)
и далее это в подрапросах джойнится с кучей других таблиц, в т.ч. с incidentsm1




так работает нормально и быстро
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
    select *
      into #data
      from get_tmp(dateadd(second, -1, @p_open_time_ukr),
                   dateadd(second, +1, @p_open_time_ukr),
                   1,   -- @p_load_tasks
                   0,   -- @p_pocopy = 
                   1,   -- @p_where_type
                   @p_folder
                )




Но когда в селект к функции добавляю ограничение по конкретному id where id = @id
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    select *
      into #data
      from get_tmp(dateadd(second, -1, @p_open_time_ukr),
                   dateadd(second, +1, @p_open_time_ukr),
                   1,   -- @p_load_tasks
                   0,   -- @p_pocopy = 
                   1,   -- @p_where_type
                   @p_folder
                )
    where request_id = @p_request_id;;

валится ошибка
Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET FORCEPLAN.
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39758840
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymx,

option(recompile)
ну, вы понимаете, к чему это ведет
с другой стороны, если это несущественно - [skipped].
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39758916
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловныandreymx,

option(recompile)
ну, вы понимаете, к чему это ведет
с другой стороны, если это несущественно - [skipped].спасибо, буду пробовать
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39758922
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxСон Веры Павловныandreymx,

option(recompile)
ну, вы понимаете, к чему это ведет
с другой стороны, если это несущественно - [skipped].спасибо, буду пробоватья так подумал
Т.к. это табличная функция
Эту опцию придётся вставлять во все её вызова?
...
Рейтинг: 0 / 0
Табличные подсказки, вычисляемое поле
    #39758926
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxЭту опцию придётся вставлять во все её вызова?Угу. Только все равно не поможет при наличии inner merge join, которого, кстати, в показонном коде нигде нет.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Табличные подсказки, вычисляемое поле
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]