powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / В представлении оптимизатор не видит индексов
25 сообщений из 26, страница 1 из 2
В представлении оптимизатор не видит индексов
    #38223973
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
[/SRC]Может быть кто-то сталкивался с такой вот проблемой.

Есть две таблицы:

[src]CREATE TABLE [_cur](
	ID bigint NOT null,
	[processed] [datetime] NOT NULL
 CONSTRAINT [pk_cur] PRIMARY KEY CLUSTERED 
(
	ID ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [transaction_current]
)



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE TABLE [_old](
	ID bigint NOT null,
	[processed] [datetime] NOT NULL
 CONSTRAINT [pk_old] PRIMARY KEY CLUSTERED 
(
	ID ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [transaction_current]
)



На каждой таблице некластерные индексы по полю processed:
Код: sql
1.
2.
3.
4.
CREATE NONCLUSTERED INDEX [idx_cur_processed] ON [_cur]
(
	[processed] DESC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [transaction_current]




Есть вьюха:

Код: sql
1.
2.
3.
4.
5.
CREATE view MyView
as
select * from _cur
union
select * from _old




Так вот, когда мы пишем запрос:

Код: sql
1.
2.
select top 10 * from _cur
order by processed desc



План запроса строиться по индексу idx_cur_processed (или idx_old_processed соответственно).

А когда мы пишем так:
Код: sql
1.
select top 10 * from MyView order by processed desc


Происходит clustered index scan.


Как мне добиться того, чтобы для этой вьюхи оптимизатор видел нужные индексы по полю processed?


Код: sql
1.
2.
3.
4.
5.
Select @@version
Microsoft SQL Server 2012 - 11.0.2100.60 (X64) 
	Feb 10 2012 19:39:15 
	Copyright (c) Microsoft Corporation
	Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38223976
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sorry, вьюха выглядит вот так:

Код: sql
1.
2.
3.
4.
5.
6.
CREATE view MyView 
as

select * from _cur with (nolock)
union all
select * from _old with (nolock)
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38223984
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_ч_Как мне добиться того, чтобы для этой вьюхи оптимизатор видел нужные индексы по полю processed?
И как по каждому индексу оптимизатор выберет _общие_ top 10 ?
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38223988
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Glory,

у меня тоже возникли такие же сомнения.
И что же теперь делать? Не использовать union all во вьюхе?
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38223993
Гость333
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_ч_А когда мы пишем так:
Код: sql
1.
select top 10 * from MyView order by processed desc


Происходит clustered index scan.
Пишите вот так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select top 10 *
from
(
   select top 10 * from _old order by processed desc
   union all
   select top 10 * from _cur order by processed desc
) t
order by t.processed desc


С такой вьюхой на таком запросе каши не сваришь...
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38223996
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_ч_у меня тоже возникли такие же сомнения.
И что же теперь делать? Не использовать union all во вьюхе?
если допустимо изменение структуры, то можно данные хранить в одной таблице вместо двух,
только надо будет добавить еще поле с признаком
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38224003
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гость333,

дело в том, что там не только индекс по полю processed. И order by может быть по другим полям.
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38224005
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shakill,

т.е. принципиально невозможно сделать так, чтобы оптимизатор приминил к этой вьюхе два индекса для каждой из таблиц?
Надо менять структуру?
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38224008
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_ч_т.е. принципиально невозможно сделать так, чтобы оптимизатор приминил к этой вьюхе два индекса для каждой из таблиц?
Каким образом, если серверу все равно придется упорядочить общий набор записей ?
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38224074
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Glory_ч_т.е. принципиально невозможно сделать так, чтобы оптимизатор приминил к этой вьюхе два индекса для каждой из таблиц?
Каким образом, если серверу все равно придется упорядочить общий набор записей ?Ну в принципе оптимизатор мог бы использовать 2 индекса так же, как использовал Гость333. Но он так не делает, не заложен такой вариант...
_ч_Надо менять структуру?Как я понимаю, эта структура сделана для ускорения работы сервера, типа душевная идея разделить базу на оперативную и архивную?

Это очередная иллюстрация того, что такое разделение в лучшем случае не делает хуже :-)
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38225379
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Glory,

Вы как всегда правы.

Значит ситуация очень плохая, т.к. индексы на представления с UNION ALL тоже не повесишь.
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38226233
Фотография SomewhereSomehow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_ч_,

Оптимизатор может использовать два некластерных индекса из двух таблиц.
Например, мог бы получиться вот такой план:


По каждому некластерному индексу выполняется упорядоченный просмотр, после чего merge и ограничение топ. В чем вопрос, не понял.
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38226264
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SomewhereSomehowОптимизатор может использовать два некластерных индекса из двух таблиц.
Например, мог бы получиться вот такой план:
Имхо
Для этого нужно очень точно проводить оценку данных.
Может оказаться, что ТОР превышает число записей в обеих таблицах
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38226411
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SomewhereSomehow,

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

|--Top(TOP EXPRESSION:((50)))
|--Merge Join(Concatenation)
|--Sort(ORDER BY:([cq].[processed] ASC, [cq].[bonus] ASC, [cq].[Id] ASC))
| |--Clustered Index Scan(OBJECT:([_old].[pk_old] AS [cq]))
|--Sort(ORDER BY:([cq].[processed] ASC, [cq].[bonus] ASC, [cq].[Id] ASC))
|--Clustered Index Scan(OBJECT:([_cur].[pk_cur] AS [cq]))


Вместо Вашего. Если бы был выбран Ваш, было бы всё в порядке. Т.е. проиходит сканирование по кластерным индексам pk_cur и pk_old, вместо более быстрого решения (сканирование по некластерным индексам idx_cur_processed и idx_old_processed).
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38226580
Фотография SomewhereSomehow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Glory,
Безусловно. Точная оценка всегда важна.

_ч_,
Судя по форме плана, есть подозрение, что те скрипты, которые вы привели могут отличаться от реальных.

В тех что вы приведены у вас:
- Два поля в таблице
- ID - ключ кластерного индекса.
- processed - ключ некластерного (в который включен кластерный по-умолчанию)

Когда вы делаете "select *" - оптимизатору все равно из какого индекса выбирать, чтобы избежать Lookup (все поля есть во всех индексах), но не все равно какой выбирать из-за порядка сортировки. По этому, выбирается тот, что который может гарантировать сортировку при сканировании, в данном случае idx_XXX_processed.

Но если условия не соблюдаются, например, какой-то из индексов, не содержит все поля, то оптимизатор может выбирать из следующих вариантов:
1. Сканировать кластерный (который содержит все поля), потом отсортировать (дорогая операция)
2. Избежать сортировки сканировав некластерный индекс, но в нужном порядке, и уже потом сделать Lookup из кластерного для недостающих полей (очень дорогая операция)
Плюс добавить в уравнение то, что оптимизатор основывается на статистике, которая не всегда актуальна.

Может быть он выбирает первый вариант, как менее затратный? Lookup очень дорого.

Попробуйте, ради эксперимента поиграть с числом в TOP, например TOP(1) или TOP(2) тоже выберет план со сканом кластерного? Если да, то, наверное, без анализа планов не обойтись. Публикуйте сюда планы в виде xml, будем смотреть на оценки, о чем говорил Glory.

Если же, при малом числе строк выбирается nonclustered index scan + key lookup, но как только число строк возрастает план скатывается в скан кластерного индекса - значит дело в этом. В таком случае, необходимо индекс делать покрывающим (т.е. добавить в него все поля которые участвуют в запросе).

Вот какие планы были бы возможны.
Подготовка:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
use tempdb;
go
CREATE TABLE [_cur](ID bigint NOT null, [processed] [datetime] NOT NULL, lookup_field int, CONSTRAINT [pk_cur] PRIMARY KEY CLUSTERED (ID ASC));
CREATE TABLE [_old](ID bigint NOT null, [processed] [datetime] NOT NULL, lookup_field int, CONSTRAINT [pk_old] PRIMARY KEY CLUSTERED (ID ASC));
go
CREATE NONCLUSTERED INDEX [idx_cur_processed] ON [_cur]([processed] DESC);
CREATE NONCLUSTERED INDEX [idx_cur_processed] ON [_old]([processed] DESC);
go
CREATE view MyView 
as
select * from _cur with (nolock)
union all
select * from _old with (nolock)
;
go
--simulate data
update statistics [_cur] with rowcount = 10000, pagecount = 100
update statistics [_old] with rowcount = 100000, pagecount = 1000
go


Запросы:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
-- both clustered scan and sort
select top (50000) * from MyView order by processed desc;
go
-- one clustered scan and sort + one nonclustered scan and lookup
select top (5000) * from MyView order by processed desc;
go
-- both nonclustered scan and lookup
select top (500) * from MyView order by processed desc;
go


Планы:


Можно сделать покрывающие индексы и повторить запросы:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
--possible workaround - create 2 covering indexex
create index idx_cur_processed_covering on [_cur]([processed] desc) include (lookup_field);
create index idx_old_processed_covering on [_old]([processed] desc) include (lookup_field);
exec sp_refreshview 'MyView' --might be important if no schema binding and table changings
go
-- both clustered scan and sort
select top (50000) * from MyView order by processed desc;
go
-- one clustered scan and sort + one nonclustered scan and lookup
select top (5000) * from MyView order by processed desc;
go
-- both nonclustered scan and lookup
select top (500) * from MyView order by processed desc;
go
--clear
drop view MyView;
drop table [_cur], [_old];


Планы:


П.С.
Если вам это не поможет, то выкладывайте сюда планы (только не картинками как я, т.к. в моем случае, реальные планы могут воспроизвести любые желающие, запустив скрипты, а свои реальные планы в формате xml, реальные еще и в том смысле, что не estimated (оценочные), а actual (реальные или актуальные), чтобы можно было сравнить оценки и действительность).
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38227032
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SomewhereSomehow,

Спасибо за заинтересованность, всё оказалось довольно запутанее.

Вот скрипт на создание таблиц и заполнение (заполняется только одна):

Код: 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.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
--Dropping tables if they exist
IF OBJECT_ID('test_a') IS NOT NULL
	DROP TABLE test_a

IF OBJECT_ID('test_b') IS NOT NULL
	DROP TABLE test_b

--Creating tables
CREATE TABLE loyalty.test_a(ID uID NOT NULL, summ DECIMAL(18, 2) NOT NULL, name NVARCHAR(40) NOT NULL, processed DATETIME NOT NULL
CONSTRAINT [pk_a] PRIMARY KEY CLUSTERED 
(
 ID ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)


CREATE TABLE test_b(ID uID NOT NULL, summ DECIMAL(18, 2) NOT null, name NVARCHAR(40) NOT null, processed DATETIME NOT null
CONSTRAINT [pk_b] PRIMARY KEY CLUSTERED 
(
 ID ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)

--Filling our tables
DECLARE @i INT = 0

WHILE @i < 4000
BEGIN
	INSERT INTO test_a (
		summ
		,NAME
		,processed
		)
	SELECT CONVERT(DECIMAL(18, 2), Column_id)
		,c.NAME
		,DATEADD(DAY, @i, o.modify_date)
	FROM sys.columns c
	JOIN sys.objects o ON o.object_id = c.object_id

	SET @i = @i + 1
END

--Creating indexes

CREATE NONCLUSTERED INDEX [idx_test_a_processed] ON test_a
(
	processed DESC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)

CREATE NONCLUSTERED INDEX [idx_test_b_processed] ON test_b
(
	processed DESC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)


--Dropping view if it exists
IF EXISTS(SELECT 1 FROM sys.views WHERE name = 'test_all')
	DROP VIEW test_all

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

--Creating view
CREATE view [test_all]
AS
	SELECT ID
			,summ
			,name
			,processed
	FROM test_b WITH (NOLOCK)
	UNION ALL
	SELECT ID
			,summ
			,name
			,processed
	FROM test_a WITH (NOLOCK)
GO




А теперь я запускаю три простых запроса (с top 50 как и на боевой базе):

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT TOP 50 * FROM test_a
ORDER BY processed

SELECT TOP 50 * FROM dbo.test_all
ORDER BY processed DESC


SELECT TOP 50 * from dbo.test_all
ORDER BY processed ASC
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38227035
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SomewhereSomehowGlory,
Безусловно. Точная оценка всегда важна.
На мой взгляд, это уже больше похоже на секционирование.
Которое и так уже есть.
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38227058
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так вот, из плана хорошо видно, что

в случае запроса

Код: sql
1.
2.
select top 50 * from test_all
order by processed desc



Оптимизатор сканирует некластерный индекс, а в случае:

Код: sql
1.
2.
select top 50 * from test_all
order by processed asc



сканирует уже кластерный.

Если поменять в некластерном индексе сортировку, то ситуация повториться с точностью до наоборот.
Если же сделать два некластерных индекса по полю procressed с сортировкой asc и desc, то план запроса строиться на сканировании только этих некластерных индексов.

Всё это происходит на двух серверах 2012.

Код: sql
1.
2.
3.
4.
5.
select @@version
Microsoft SQL Server 2012 - 11.0.2100.60 (X64) 
	Feb 10 2012 19:39:15 
	Copyright (c) Microsoft Corporation
	Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)



Сейчас буду ставить SP1 и тестировать там эту особенность поведения оптимизатора.
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38227134
Мистер Хенки
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А не желаете в некластерный индекс добавить в виде include полей summ и name, чтобы не тратить ресурсы на операцию key lookup ?
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38227150
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мистер Хенки,

В данном случае меня интересует вопрос как так получилось, что порядок сортировки в индексе и запросе влияет на выбор оптимизатора.
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38227224
Мистер Хенки
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_ч_Мистер Хенки,

В данном случае меня интересует вопрос как так получилось, что порядок сортировки в индексе и запросе влияет на выбор оптимизатора.
потому что merge выдаст поток данных отсортированный в desc порядке(порядок у индексов) и надо будет еще его сортировать, чтобы сделать order by asc- как то так видимо. Если создадите покрывающие индексы, то увидете, что оптимизатор выберет их использование, но все равно будет сортировать перед merge join
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38227255
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мистер Хенки,

воспользовался Вашим советом.

Теперь планы выглядят так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT TOP 50 name, id, processed, summ FROM dbo.test_all2
ORDER BY processed DESC	1	1	0	NULL	NULL	1	NULL	50	NULL	NULL	NULL	1,360734	NULL	NULL	SELECT	0	NULL
  |--Top(TOP EXPRESSION:((50)))	1	2	1	Top	Top	TOP EXPRESSION:((50))	NULL	50	0	5E-06	76	1,360734	[Union1006], [Union1007], [Union1008], [Union1009]	NULL	PLAN_ROW	0	1
       |--Merge Join(Concatenation)	1	3	2	Merge Join	Concatenation	NULL	[Union1009] = ([DB].[dbo].[test_b2].[processed], [DB].[dbo].[test_a2].[processed]), [Union1006] = ([DB].[dbo].[test_b2].[ID], [DB].[dbo].[test_a2].[ID]), [Union1007] = ([DB].[dbo].[test_b2].[summ], [DB].[dbo].[test_a2].[summ]), [Union1008] = ([DB].[dbo].[test_b2].[name], [DB].[dbo].[test_a2].[name])	50	0	1,336834	76	1,360729	[Union1009], [Union1006], [Union1007], [Union1008]	NULL	PLAN_ROW	0	1
            |--Sort(ORDER BY:([DB].[dbo].[test_b2].[processed] DESC, [DB].[dbo].[test_b2].[ID] ASC))	1	4	3	Sort	Sort	ORDER BY:([DB].[dbo].[test_b2].[processed] DESC, [DB].[dbo].[test_b2].[ID] ASC)	NULL	1	0,01126126	0,000100076	76	0,01464444	[DB].[dbo].[test_b2].[ID], [DB].[dbo].[test_b2].[summ], [DB].[dbo].[test_b2].[name], [DB].[dbo].[test_b2].[processed]	NULL	PLAN_ROW	0	1
            |    |--Index Scan(OBJECT:([DB].[dbo].[test_b2].[idx_test_b_processed]))	1	5	4	Index Scan	Index Scan	OBJECT:([DB].[dbo].[test_b2].[idx_test_b_processed])	[DB].[dbo].[test_b2].[ID], [DB].[dbo].[test_b2].[summ], [DB].[dbo].[test_b2].[name], [DB].[dbo].[test_b2].[processed]	1	0,003125	0,0001581	76	0,0032831	[DB].[dbo].[test_b2].[ID], [DB].[dbo].[test_b2].[summ], [DB].[dbo].[test_b2].[name], [DB].[dbo].[test_b2].[processed]	NULL	PLAN_ROW	0	1
            |--Sort(ORDER BY:([DB].[dbo].[test_a2].[processed] DESC, [DB].[dbo].[test_a2].[ID] ASC))	1	6	3	Sort	Sort	ORDER BY:([DB].[dbo].[test_a2].[processed] DESC, [DB].[dbo].[test_a2].[ID] ASC)	NULL	49	1897,646	529,5381	76	1,360734	[DB].[dbo].[test_a2].[ID], [DB].[dbo].[test_a2].[summ], [DB].[dbo].[test_a2].[name], [DB].[dbo].[test_a2].[processed]	NULL	PLAN_ROW	0	1
                 |--Index Scan(OBJECT:([DB].[dbo].[test_a2].[idx_test_a_processed]))	1	7	6	Index Scan	Index Scan	OBJECT:([DB].[dbo].[test_a2].[idx_test_a_processed])	[DB].[dbo].[test_a2].[ID], [DB].[dbo].[test_a2].[summ], [DB].[dbo].[test_a2].[name], [DB].[dbo].[test_a2].[processed]	1,33123E+07	71,98164	14,64368	76	1,360734	[DB].[dbo].[test_a2].[ID], [DB].[dbo].[test_a2].[summ], [DB].[dbo].[test_a2].[name], [DB].[dbo].[test_a2].[processed]	NULL	PLAN_ROW	0	1

SELECT TOP 50 name, id, processed, summ from dbo.test_all2
ORDER BY processed ASC	2	8	0	NULL	NULL	2	NULL	50	NULL	NULL	NULL	1,340439	NULL	NULL	SELECT	0	NULL
  |--Top(TOP EXPRESSION:((50)))	2	9	8	Top	Top	TOP EXPRESSION:((50))	NULL	50	0	5E-06	76	1,340439	[Union1006], [Union1007], [Union1008], [Union1009]	NULL	PLAN_ROW	0	1
       |--Merge Join(Concatenation)	2	10	9	Merge Join	Concatenation	NULL	[Union1009] = ([DB].[dbo].[test_b2].[processed], [DB].[dbo].[test_a2].[processed]), [Union1006] = ([DB].[dbo].[test_b2].[ID], [DB].[dbo].[test_a2].[ID]), [Union1007] = ([DB].[dbo].[test_b2].[summ], [DB].[dbo].[test_a2].[summ]), [Union1008] = ([DB].[dbo].[test_b2].[name], [DB].[dbo].[test_a2].[name])	50	0	1,336834	76	1,340434	[Union1009], [Union1006], [Union1007], [Union1008]	NULL	PLAN_ROW	0	1
            |--Index Scan(OBJECT:([DB].[dbo].[test_b2].[idx_test_b_processed]), ORDERED FORWARD)	2	11	10	Index Scan	Index Scan	OBJECT:([DB].[dbo].[test_b2].[idx_test_b_processed]), ORDERED FORWARD	[DB].[dbo].[test_b2].[ID], [DB].[dbo].[test_b2].[summ], [DB].[dbo].[test_b2].[name], [DB].[dbo].[test_b2].[processed]	1	0,003125	0,0001581	76	0,0032831	[DB].[dbo].[test_b2].[ID], [DB].[dbo].[test_b2].[summ], [DB].[dbo].[test_b2].[name], [DB].[dbo].[test_b2].[processed]	NULL	PLAN_ROW	0	1
            |--Index Scan(OBJECT:([DB].[dbo].[test_a2].[idx_test_a_processed]), ORDERED FORWARD)	2	12	10	Index Scan	Index Scan	OBJECT:([DB].[dbo].[test_a2].[idx_test_a_processed]), ORDERED FORWARD	[DB].[dbo].[test_a2].[ID], [DB].[dbo].[test_a2].[summ], [DB].[dbo].[test_a2].[name], [DB].[dbo].[test_a2].[processed]	49	71,98164	14,64368	76	0,003595432	[DB].[dbo].[test_a2].[ID], [DB].[dbo].[test_a2].[summ], [DB].[dbo].[test_a2].[name], [DB].[dbo].[test_a2].[processed]	NULL	PLAN_ROW	0	1





Уже лучше, за тем исключением, что первый запрос отрабатывает 15 секунд, а второй доли секунд.
А еще огромный минус в том, что полей в реальной таблице, а не тестовой гораздо больше.
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38227265
_ч_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
План картинкой, кому лень скачивать xml.


Теперь версия сервера
авторMicrosoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64)
Oct 19 2012 13:38:57
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38227364
Мистер Хенки
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_ч_Мистер Хенки,

воспользовался Вашим советом.


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

Тогда возвращайтесь к первоначальному варианту и указывайте кластерный ключ явно при сортировке
Код: sql
1.
2.
3.
4.
5.
SELECT TOP 50 * FROM dbo.test_all
ORDER BY processed DESC,ID asc


SELECT TOP 50 * from dbo.test_all order by processed ASC,ID desc
...
Рейтинг: 0 / 0
В представлении оптимизатор не видит индексов
    #38227509
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_ч_Glory,

у меня тоже возникли такие же сомнения.
И что же теперь делать? Не использовать union all во вьюхе?

Да вообще лучше View не использовать.
На кой оно тебе ?
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / В представлении оптимизатор не видит индексов
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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