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

Родились 2 варианта:
1)
select distinct catalog_item.item_id
from catalog_item
LEFT OUTER JOIN item_node
INNER JOIN node ON item_node.node_id = node.node_id
ON catalog_item.item_id = item_node.item_id
where exists( select * from item_node where node_id=1 and catalog_item.item_id=item_id )
and exists( select * from item_node where node_id=123 and catalog_item.item_id=item_id )
and exists( select * from item_node where node_id=125 and catalog_item.item_id=item_id )
and exists( select * from item_node where node_id=138 and catalog_item.item_id=item_id )
and exists( select * from item_node where node_id=174 and catalog_item.item_id=item_id )
and exists( select * from item_node where node_id=190 and catalog_item.item_id=item_id )

2)
select item_id from
(select catalog_item.item_id as item_id, count(*) as number
from catalog_item
LEFT OUTER JOIN item_node
INNER JOIN node ON item_node.node_id = node.node_id
ON catalog_item.item_id = item_node.item_id
where item_node.node_id in (1,123,125,138,174,190)
group by catalog_item.item_id) a where number=6

Выполняются они примерно одинаковое время, причем на меньшем количестве выбранных параметров быстрее 1-й вариант. Как будет зависить соотношение времени выполнения этих запросов от количества данных в этих таблицах и количества выбранных пользователем возможностей?
...
Рейтинг: 0 / 0
производительность
    #32011007
Slava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По моему лучше всего самому проверить, создав большое количество данных вручную, а потом понять почему тот или иной вариант быстрее.
Вообще в первом варианте вроде куча лишних селектов, но экспериментальным путем я выяснил, что самый медленный запрос это select * from Table where Field in (select field from table), короче in это тормоз(наверно). быстрей будет так select t1.* from table1 t1 inner join table t2 on t1.field1 = t2.field2.
Так же тормозят left и right, что бы избежать этого надо в обоих таблицах кластерные индексы делать, тогда перед объединением сервер не будет выполнять сортировку, но круче всего объединение проводить по столбцам с primary key.
Посылаю Вам скрипт который демонстрирует все что я сказал

-- Часть первая
/*declare @t1 table(id int)
declare @t2 table(id int, id_t1 int)
declare @i int
set @i = 1
while @i < 1001 begin
insert into @t1 values(@i)
insert into @t2 values(@i, @i)
set @i = @i + 1
end
declare @d datetime
set @d = getdate()
select id from @t1 where id in (select id from @t2)
--select t1.id from @t1 t1 inner join @t2 t2 on t1.id = t2.id
select getdate() - @d*/

-- Часть вторая
create table t1(id int /*primary key*/)
create table t2(id int /*primary key*/)
--create clustered index ClusteredIndex on t1(id)
--create clustered index ClusteredIndex on t2(id)
declare @i int
set @i = 1
while @i < 7001 begin
insert into t1 values(@i)
insert into t2 values(7001 - @i)
set @i = @i + 1
end
declare @d datetime
set @d = getdate()
select t1.id from t1 t1 left join t2 t2 on t1.id = t2.id
select getdate() - @d
drop table t1
drop table t2
...
Рейтинг: 0 / 0
производительность
    #32011087
andy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Разумеется индексы проставлены, какие только можно, никаких table scan'ов в планах нет. Проводить тестирование "вручную" просто нет времени. Это ж надо менять сразу несколько параметров и смотреть на результат, тут только для этой цели ОЛАПом воспользоваться придется . Вопрос состоял в том, чтоб предсказать, как это будет работать при увеличении объема данных. Там и сейчас тысяч 10 есть в catalog_item, ~200 node ~20000 item_node. Выполняется первый запрос за 620мс, а второй за 670мс. При выборе с 4-мя условиями разница была значительно больше.

На самом деле рассматривалось 4 варианта, но 2 других перевалили за 3 секунды. И следовательно отпали сразу.

Могу сформулировать задачу словами, может кто предложит, более приемлемый вариант:
Надо выбрать из таблицы catalog_item только те строки, которые совместимы со всеми выбранными пользователем значениями из node, т.е. таблица item_node содержит связи этого item_id со всеми node_id из условия.
...
Рейтинг: 0 / 0
производительность
    #32011098
Если я правильно понял задачу, то можно построить запрос по одной таблице item_node:

select item_id
from item_node
where node_id in (1,123,125,138,174,190)
group by item_id
having count(distinct node_id)=6

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


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