|
|
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
Есть запрос, схематично которой можно записать в виде Код: plsql 1. 2. 3. 4. 5. 6. 7. Т.е. значение из одно и того же множества значений проверяется на совпадение в одном из 4х атрибутов. Если на примере, то, допустим, есть выделенная группа экспертов '1' {'значение_1', 'значение_2', 'значение_3', 'значение_4'}. Допустим, эксперт ('значение_1') на сайте вызывает диалог, в результате которого должны отобразиться все заявки ('table_1'). При этом должны вывестись такие заявки, где этот эксперт ('значение_1') или остальные эксперты из его группы '1' ('значение_2', 'значение_3', 'значение_4') являются либо рецензентами ('field_1'), либо field_2, либо field_3, либо field_4. Предлагается переделать структура запроса либо структуру данных (вплоть до дополнительных таблиц) так, чтобы не было OR и/или IN ( мотивация: на больших данных запрос долго работает ). Есть идеи? Используется Oracle 10g. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2011, 18:42 |
|
||
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
Всегда, когда возникают поля вида field_N, нужно подумать, а не лучше ли будет эти поля хранить в виде отдельных записей? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2011, 19:00 |
|
||
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
miksoftВсегда, когда возникают поля вида field_N, нужно подумать, а не лучше ли будет эти поля хранить в виде отдельных записей? Т.е., как вариант, сделать доп. таблицу, где все значения из 4х field_N будут хранится в одном поле, да? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2011, 19:37 |
|
||
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
Энтри_N3miksoftВсегда, когда возникают поля вида field_N, нужно подумать, а не лучше ли будет эти поля хранить в виде отдельных записей? Т.е., как вариант, сделать доп. таблицу, где все значения из 4х field_N будут хранится в одном поле, да?Да. Только, конечно, нужно еще учитывать что и где это за собой потянет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2011, 19:48 |
|
||
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
Энтри_N3, да, типа table2(id_table1, field_name , field_value) id_table1;field_name;field_value1;1;'значение_1'1;2;'значение_3'1;3;'значение_1'1;4;'значение_2' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2011, 19:51 |
|
||
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
Для начала скажу, что корежить структуру для одного запроса может оказаться плохой идеей. Далее, оптимизация таких запросов сильно зависит от данных. Какой процент таблицы возвращается запросом? Какое количество полей пустые (содержат null). Как быстро выполняется простые запросы Код: sql 1. Энтри_N3 Т.е. значение из одно и того же множества значений проверяется на совпадение в одном из 4х атрибутов.Это единственное условие? То есть никаких дополнительных ограничивающих условий типа за прошлый год, или для этого продукта/магазина/отдела. Смотрите сами: если поля проиндексированы ваш запрос дает соединение 4*4=16 индексных сканов. В таких условиях один полный скан (или индексный скан по другому индексу) легко может оказаться предпочтительнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2011, 20:42 |
|
||
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
для более-менее постоянных перечислений встречал решение на битовых флагах. плюсы - в производительности минусы - в читабельности кода и представлении наименований вместо флагов на стороне БД и приложения. первые попавшиеся ссылки: stackoverflow forum topic bit masks in sql sqlteam forum topic oracle поддерживает bitmap-индексы - есть смысл посмотреть эту тему также. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2011, 15:24 |
|
||
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
On 12/09/2011 07:42 PM, Энтри_N3 wrote: > select * > from table_1 > where (field_1 IN ('значение_1','значение_2','значение_3','значение_4') > or field_2 IN ('значение_1','значение_2','значение_3','значение_4') > or field_3 IN ('значение_1','значение_2','значение_3','значение_4') > or field_4 IN ('значение_1','значение_2','значение_3','значение_4') > ) 1) Если тебе надо проверять наличие значения в нескольких полях, как тут, -- это ошибки в проектировании БД, нарушение 1ой нормальной формы Рецепт - редизайт, эти поля пойдут в отдельную дочернюю таблицу 1:N с данной таблицей. После "лечения" запрос будет примерно таким: select * from table_1 t1 join table_1_fields t1f on t1f.t1pk = t1.pk where t1f.field IN ('значение_1','значение_2','значение_3','значение_4') 2) Избавляться от IN ('значение_1','значение_2','значение_3','значение_4') в принципе уже не обязательно, если значений в IN немного. Но если хочется -- делается временная таблица "список проверяемых значений" (check_list) с одним полем -- field, оно же бывшее field1...fieldN и идентификатором сессии пользователя user_session_id. И запрос превращается в select * from table_1 t1 join table_1_fields t1f on t1f.t1pk = t1.pk join check_list chl on chl.field = t1f.field where chl.user_session_id = curent_user_session_id() Для правильной работы этого запроса в любых условиях, даже когда оптимизатор не догадывается, что check_list-- это таблица-фильтр, нужно форсануть план, чтобы таблица check_list была бы первой в запросе, т.е. по уму данный запрос должен выполняться "снизу вверх" как он у меня тут написан. Если оптимизатор догадается сам, то и хорошо. На самом деле ещё раз, вовсе не обязательно делать второй шаг, поскольку совсем не очевидно, что будет оптимизироваться лучше, запрос после шага 1, или после шага 2. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2011, 15:50 |
|
||
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
> Для начала скажу, что корежить структуру для одного запроса может оказаться > плохой идеей. А я скажу для продолжения, что если это наруш. 1НФ, то оно будет сказываться НА ВСЕХ запросах, затрагивающих это поле. Этот запрос -- только первая ласточка. Для хороших запросов БД должна быть хорошо спроектирована. Так что чем раньше -- тем лучше. > Далее, оптимизация таких запросов сильно зависит от данных. Какой процент > таблицы возвращается запросом? Какое количество полей пустые (содержат null). Да ладно, тут -то как раз всё ясно. N полей в OR, и M значений в IN, получается либо делать table scan, либо выполнять N * M позиционирований по индексу по полю field1..fieldN Это даже тут уже 16. Если бы тут что-то зависело от данных, т.е. распределение данных было бы плохое, невыгодное для индексирования, было бы всё равно, как этот запрос выполнялся бы -- в любом случае это было бы медленно. > Как быстро выполняется простые запросы > > select * from table_1where field_1IN ('значение_1' ) logN (размер таблицы). Если есть индекс. Если нет -- автор бы не спрашивал. > Смотрите сами: если поля проиндексированы ваш запрос дает соединение 4*4=16 > индексных сканов. В таких условиях *один* полный скан (или индексный скан по > другому индексу) легко может оказаться предпочтительнее. Ну вот, понимаешь же, а чего тогда про данные тут выспрашивал? Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2011, 15:58 |
|
||
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
Всем спасибо за ценные ответы. Буду вчитываться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.12.2011, 14:04 |
|
||
|
Рефакторинг запроса с IN и OR (участники группы с совпадением в нескольких полях)
|
|||
|---|---|---|---|
|
#18+
MasterZiv Для хороших запросов БД должна быть хорошо спроектирована. Так что чем раньше - тем лучше.Кто бы спорил. MasterZiv Если бы тут что-то зависело от данных, т.е. распределение данных было бы плохое, невыгодное для индексирования, было бы всё равно, как этот запрос выполнялся бы -- в любом случае это было бы медленно.Вот именно на этот вопрос я и жду ответ начальника транспортного цеха. Подтверждение того что игра стоит свеч. MasterZiv logN (размер таблицы). Если есть индекс. Если нет -- автор бы не спрашивал.Для одной записи да. И для многих, если таблица хорошо кластеризована тоже да (M*logN мало отличается от logN ). А если записей много и они размазаны по блокам, то уже нет. Короче 1 прежде чем что либо оптимизировать надо вооружится измерительным инструментом - запрос долго работает не является самым лучшим инструментом. Я предлагаю считать логические чтения 2 прежде чем менять структуру (и точно иметь гемор с этим связаный) предлагаю определить заранее, что овчинка стоит выделки. Запустите мой запрос на самых плохих данных ('значение_1', 'значение_2', 'значение_3', 'значение_4') и это будет ваш наилучший результат. Подтвердите, что других ограничителей (кроме field_1 .. field_4) нет Замерьте: сколько строк (в проценте от общего количества) возвращает ваш (большой) запрос при наихудших и типичных значениях. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.12.2011, 18:39 |
|
||
|
|

start [/forum/topic.php?fid=32&tid=1541903]: |
0ms |
get settings: |
11ms |
get forum list: |
18ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
151ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
| others: | 228ms |
| total: | 472ms |

| 0 / 0 |
