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

Откуда:
Сообщений: 552
Приветствую

Есть большая таблица
120 патриций по +- 20М записей в каждой...

Есть набор записей id1 - date_field в кол-е 600к-1М которьіе вьібирают из
разньіх партиций по +-500 записей

схема
+
create large_table
	(
	   datetime_field datetime not null -- full date and time
	  ,id1 bigint not null
	  ,id2 bigint not null
	  ,my_target_field nvarchar(100)
	  -- rest of the fields
	) -- ON <partitioned by a calendar day>

	create unique clustered index cix_large_table_pk on large_table (  
	   datetime_field 
	  ,id1 
	  ,id2 
	)

	create index ix_large_table_id1 on large_table (  
	  id1 
	)

	create table random_subset_of_large_table
	(
	   id1 bigint not null
	  ,date_field datetime not null -- only date without time fraction
	)

  create clustered index 
    cix_random_subset_of_large_table_id1 on random_subset_of_large_table (
      id1 )


вещи вроде такого "не возвращаются"

-- date_field = convert(date, datetime_field)
select lt.my_target_field
from large_table as lt
join random_subset_of_large_table as rs on 
    lt.datetime_field >= rs.date_field
    and lt.date_field < dateadd(day, 1, rs.date_field)
    and lt.id1 = rs.id1


возможно самьій лучший план:
nested loops
index scan cix_random_subset_of_large_table_id1
+index seek cix_large_table_pk

вопрос1 - будет ли лучше работать решение с merge join ?
вопрос2 - будет ли лучше написать курсор-цикл и "целиться" в 1-у
партицию в итериции

буду признателен за рекомендации по решению подобньіх задач
пс. индекс по my_target_field не предлагать
8 фев 20, 04:12    [22075894]     Ответить | Цитировать Сообщить модератору
 Re: Запрос к большой таблице  [new]
aleks222
Member

Откуда:
Сообщений: 817
1. Минимум
	create table random_subset_of_large_table
	(
	   id1 bigint not null
	  , date_field date not null -- only date without time fraction
          , unique clustered index (  datetime_field , id1 )
	)


2. lt.id1 = rs.id1 значения для точного равенства следует ставить в индексах ПЕРВЫМИ.
	create table random_subset_of_large_table
	(
	   id1 bigint not null
	  , date_field date not null -- only date without time fraction
          , unique clustered index (  id1, datetime_field  )
	)


НО! это надо сделать и в большой таблице.

create UNIQUE index ix_large_table_id1 on large_table (  
	  id1, date_field, id2
	)


Сообщение было отредактировано: 8 фев 20, 09:12
8 фев 20, 09:12    [22075911]     Ответить | Цитировать Сообщить модератору
 Re: Запрос к большой таблице  [new]
Александр Бердышев
Member

Откуда: Санкт-Петербург
Сообщений: 345
В 1 таблице кластеризованный индекс сначала по дате, потом по id1, во второй таблице - по id1.
Во-первых, join лучше делать по условию что T1.id1 = T2.id1, а потом уже другие условия.
Во вторых: поскольку в 1 таблице в кластеризованном индексе сортировка в 1 очередь по дате - физически на страницах памяти в базе будет всё упорядочено по дате, а потом уже по id1.
Если пересоздать кластеризованный индекс 1 таблицы так, чтобы упорядочить в 1 очередь по id1 - то можно будет сделать merge join - он должен быстрее всего работать.

Ещё рекомендую посмотреть, как сделать чтобы записи джоинились только в рамках своей партиции - рекомендую во второй таблице на этот случай завести ключ к партиции из первой таблицы и в первую очередь джоиниться по нему, а уже во вторую - по индексу.
Конечно при условии, что у вас индекс тоже партиционированный. При этом условие по партиции должно быть строго равно, без всяких больше или равно.
12 фев 20, 19:50    [22078756]     Ответить | Цитировать Сообщить модератору
 Re: Запрос к большой таблице  [new]
msLex
Member

Откуда:
Сообщений: 7600
Александр Бердышев
и в первую очередь джоиниться по нему, а уже во вторую - по индексу.

т.е.
on a.id = b.id  and a.partition_key = b.partition_key

хуже чем
on a.partition_key = b.partition_key and a.id = b.id

?
12 фев 20, 20:04    [22078768]     Ответить | Цитировать Сообщить модератору
 Re: Запрос к большой таблице  [new]
invm
Member

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

Попробуйте так
select
 lt.my_target_field
from 
 random_subset_of_large_table as rs inner loop join
 large_table as lt on $partition.MyPartitionFunction(lt.datetime_field) = $partition.MyPartitionFunction(rs.date_field) and lt.id1 = rs.id1
12 фев 20, 20:41    [22078784]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить