Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
производительность
|
|||
|---|---|---|---|
|
#18+
Есть задачка: Три таблицы, связь многие ко многим, надо выбрать все товары, которые связаны со всеми указанными сущностями из 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-й вариант. Как будет зависить соотношение времени выполнения этих запросов от количества данных в этих таблицах и количества выбранных пользователем возможностей? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2001, 17:10 |
|
||
|
производительность
|
|||
|---|---|---|---|
|
#18+
По моему лучше всего самому проверить, создав большое количество данных вручную, а потом понять почему тот или иной вариант быстрее. Вообще в первом варианте вроде куча лишних селектов, но экспериментальным путем я выяснил, что самый медленный запрос это 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 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.08.2001, 01:36 |
|
||
|
производительность
|
|||
|---|---|---|---|
|
#18+
Разумеется индексы проставлены, какие только можно, никаких 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 из условия. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.08.2001, 19:09 |
|
||
|
производительность
|
|||
|---|---|---|---|
|
#18+
Если я правильно понял задачу, то можно построить запрос по одной таблице 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 в запросе, может опишете поподробней структуру таблиц. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2001, 11:50 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32011007&tid=1825978]: |
0ms |
get settings: |
7ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
27ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
38ms |
get tp. blocked users: |
1ms |
| others: | 239ms |
| total: | 344ms |

| 0 / 0 |
