powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Почему такой план (Index Scan)
8 сообщений из 8, страница 1 из 1
Почему такой план (Index Scan)
    #39635331
newLoginSql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите пожалуйста почему такой план получается в первом запросе.

Таблица:
Код: 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.
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Links](
	[Source] [int] NOT NULL,
	[Destination] [int] NOT NULL,
	[Date] [datetime] NULL DEFAULT (getdate()),
	[TypeID] [smallint] NOT NULL,
 CONSTRAINT [PK_Links] PRIMARY KEY CLUSTERED 
(
	[Source] ASC,
	[TypeID] ASC,
	[Destination] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE NONCLUSTERED INDEX [IX_Links_Destination] ON [dbo].[Links]
(
	[Destination] ASC,
	[TypeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO



Тестовые данные:
Код: sql
1.
2.
3.
INSERT INTO [dbo].[Links]([Source], [Destination], [Date], [TypeID])
SELECT o.[object_id], o2.[object_id], GETDATE(), 1 FROM sys.[objects] o
CROSS JOIN sys.[objects] o2 



Запрос:
Код: 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.
IF OBJECT_ID('tempdb..#Inserted') IS NOT NULL DROP TABLE #Inserted
CREATE TABLE #Inserted 
(
  [ID] Int NOT NULL PRIMARY KEY CLUSTERED
) 

INSERT INTO #Inserted([ID])
SELECT TOP (10) o.[object_id] FROM sys.[objects] o 


SELECT DISTINCT
  [ID] = CASE WHEN I.[ID] = TL.[Source] THEN TL.[Destination] ELSE TL.[Source] END
FROM [dbo].[Links] TL
INNER JOIN #Inserted I ON I.[ID] = TL.[Source]
  OR I.[ID] = TL.[Destination]


SELECT DISTINCT
  TL.[Destination]
FROM [dbo].[Links] TL
INNER JOIN #Inserted I ON I.[ID] = TL.[Source]
UNION
SELECT DISTINCT
  TL.[Source]
FROM [dbo].[Links] TL
INNER JOIN #Inserted I ON I.[ID] = TL.[Destination]



В первом случае (с OR в соединении) Index Scan.
Во втором (с UNION) Index Seek. Почему?
...
Рейтинг: 0 / 0
Почему такой план (Index Scan)
    #39635343
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Потому что не умеет сервер разворачивать OR в два сика с объединением. И, вроде, не научили еще (но это не точно).
...
Рейтинг: 0 / 0
Почему такой план (Index Scan)
    #39635728
nullin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
newLoginSql, Зачем Вам вообще OR?
Код: sql
1.
2.
3.
4.
5.
6.
SELECT DISTINCT
       [ID] = CASE WHEN I.[ID] = TL.[Source] THEN TL.[Destination] ELSE TL.[Source] END
  FROM [dbo].[Links] TL
 CROSS APPLY (SELECT [V] = 1 UNION ALL SELECT [V] = 0) X
 INNER JOIN #Inserted I 
    ON I.[ID] = TL.[Destination]
...
Рейтинг: 0 / 0
Почему такой план (Index Scan)
    #39635731
nullin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
nullin, вместо cross apply, еще можно заставить seek by fake left join (on 1=1) того же набора из двух значений.
...
Рейтинг: 0 / 0
Почему такой план (Index Scan)
    #39635799
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nullinnewLoginSql, Зачем Вам вообще OR?
Код: sql
1.
2.
3.
4.
5.
6.
SELECT DISTINCT
       [ID] = CASE WHEN I.[ID] = TL.[Source] THEN TL.[Destination] ELSE TL.[Source] END
  FROM [dbo].[Links] TL
 CROSS APPLY (SELECT [V] = 1 UNION ALL SELECT [V] = 0) X
 INNER JOIN #Inserted I 
    ON I.[ID] = TL.[Destination]


агонь! можно сократить до SELECT 1 какая разница
...
Рейтинг: 0 / 0
Почему такой план (Index Scan)
    #39635833
nullin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaK, А что Вам там не нравится?
sqlfiddle
...
Рейтинг: 0 / 0
Почему такой план (Index Scan)
    #39635834
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nullinTaPaK, А что Вам там не нравится?
sqlfiddle
ну если упёртый, то расскажи
когда же I.[ID] = TL.[Source] случится в вашей агонии?
...
Рейтинг: 0 / 0
Почему такой план (Index Scan)
    #39635909
nullin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaK, да, Вы правы, хотел обойти OR, но что-то пошло не так.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
WITH TLC as
(SELECT TL.[Source], TL.[Destination], X.[V],
        [CROSS] = CASE WHEN X.[V] = 1 THEN TL.[Destination] ELSE TL.[Source] END
   FROM [dbo].[Links] TL
  CROSS APPLY (SELECT [V] = 1 UNION ALL SELECT [V] = 0) X) 
 
 SELECT DISTINCT
        [ID] = CASE WHEN TLC.[V] = 1 THEN TLC.[Source] 
                    WHEN TLC.[V] = 0 THEN TLC.[Destination] 
               END
   FROM TLC
  INNER JOIN #Inserted I 
     ON I.[ID] = TLC.[CROSS];


Seek не запустился.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Почему такой план (Index Scan)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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