|
|
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
Сразу прошу прощения, если мой вопрос FAQовый. Что-то я не могу сообразить как сделать такую в общем-то достаточно стандартую вещь. Есть две таблицы t1 и t2. Необходимо найти пересечение их по нескольким полям. Однако! NULL в полях надо интерпретировать в соответствии с теорией реляционных БД - равен любому значению. То есть t1 f1 f2 f3 -------------- 1 А 10 2 NULL 20 3 В 20 t2 f11 f12 f13 -------------- 1 А 10 2 Б 20 3 В 20 4 Г 20 5 Д 30 Пересекаем по f2 <-> f12 и f3 <-> f13 Результат f1 f2 f3 f11 f12 f13 --------------------------------- 1 А 10 1 А 10 <-- точное совпадение 2 NULL 20 2 Б 20 <-- неточное совпадение 2 NULL 20 3 В 20 <-- неточное совпадение 2 NULL 20 3 Г 20 <-- неточное совпадение 3 В 20 3 В 20 <-- точное совпадение Надеюсь понятно. Если надо дополнительно разъяснить, то прошу. Спасибо всем откликнувшимся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2002, 17:39:48 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
ой блин.... зарапортовался... результат f1 f2 f3 f11 f12 f13 --------------------------------- 1 А 10 1 А 10 <-- точное совпадение 2 NULL 20 2 Б 20 <-- неточное совпадение 2 NULL 20 3 В 20 <-- неточное совпадение 2 NULL 20 4 Г 20 <-- неточное совпадение 3 В 20 3 В 20 <-- точное совпадение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2002, 17:41:36 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
Нет, надо что-то делать мне с собой... Не могу сразу всё написать :) Главное условие! Должно работать быстро, то есть использовать индексы. Можно использовать дополнительные поля, функциональные индексы, что угодно. В одну сторону я сделал where f2 like ISNULL(f12, '%') но хочется в обе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2002, 17:46:44 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
А может подойти с другой стороны? сначала построить декартово произведение а потом убрать лишнее? но это выгодно бутет если убираемых строк не много. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 10:32:55 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
Насколько я знаю реляционные основы БД, декартово произведение строится просто при перечислении доменов во FROM. А вот как убрать лишнее? Это вопрос :) Кто из великих скульпторов сказал, Роден что ли, что ваять скульптуры просто - берёшь глыбу и отсекаешь всё лишнее. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 10:43:01 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
Опять забыл написать :) всё-таки надо что-то с головой делать... Я почему так тему-то назвал? Идея такова, что при встрече NULLа в поле слева или справа, это условие как бы убирается из рассмотрения. То есть получается, что для неNULLовых полей f1 или f11 условие выглядит так WHERE f1 = f11 AND f2 = f12 а если в записи в f1 или f11 есть NULL, то условие приевращается (брюки превращаются...) WHERE f2 = f12 Вот и получается, что в WHERE число условий переменное и зависит от содержания полей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 10:47:19 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
Так вот: Код: plaintext 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. 28. 29. 30. 31. 32. 33. 34. 35. 36. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 10:53:20 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
2 Jimmy Не то - план смотрел? Там table scan с обеих сторон create index ndxt1f1 on test1(f1) create index ndxt1f2 on test1(f2) create index ndxt1f3 on test1(f3) create index ndxt2f11 on test2(f11) create index ndxt2f12 on test2(f12) create index ndxt2f13 on test2(f13) не помогает - убирается table scan с одной только, а хотелось бы с обеих. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 11:36:14 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
KonstN Я знаю точно одну вещь - нельзя заниматься оптимизацией прямо в процессе разработки, когда нет еще полной картины работающей системы, т.к.: 0. В первую очередь нужно реализовать конкретную задачу . В нашем случае - получить конкретную выборку 1. План запроса сильно зависит от количества записей , и при малых объемах оптимизатору действительно препочтительнее использовать Table scan, т.к. быстрее будет. 2. Даже если план запроса кажется неоптимальным, производительность может быть вполне удовлетворительной и пользователи просто не заметят результатов оптимизации. 4. Оптимизируя какой-либо запрос можно существенно замедлить прочие операции, т.к. количество индексов и качество индексов влияет на INSERT|UPDATE операции. Поэтому, вплотную оптимизацией стоит заниматься только если пользователи реальной системы об этом просят и согласны пойти на некоторые жертвы в части другой функциональности. Причем, это не мои идеи, а принципы экстремального программирования - ИМХО достаточно верной методики создания ПО малыми коллективами в короткие сроки. ЗЫ А для оптимизации (если она действительно нужна ) попробуй воспользоваться Index Tuning Wizard'ом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 12:07:57 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
2 Jimmy 0. конкретная задача - получить вышеуказанную выборку наиболее быстрым способом, что, как правило, происходит при index seek в указанных условиях 1. таблицы очень не маленькие - с одной стороны полмиллиона и с другой полста тысяч да, при малых объёмах table scan может быть быстрее, но дело в том, что план твоего запроса не изменится при увеличении количества записей, всё равно скан будет, что неприемлемо 2. производительность в высшей степени неудовлетворительна - реальная задача выполняется шесть часов, правда, там есть дополнительные служебные вызовы была бы удовлетворительна, сюда бы не писал - нет пока времени для теоретических умствований 4. истину глаголешь! однако я ничего не говорил про DML операции, мне нужен быстрый select, не зря ж упомянул фун. индексы и доп. поля я пользователь, и я не удовлетворён с какой скоростью у меня проезжает скрипт по импорту данных. ЗЫ Index Tuning Wizard может помочь только с настройкой индексов для определённых запросов. А у меня он ещё не определён! А для твоего запроса с table scanом он вообще как собаке стоп-сигнал поможет. Принципы ХР тут совсем ни к чему - задача стоит конкретнее некуда, нужна идея, а не принципы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 13:06:29 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
Ну ладно, попробую поконкретней свою мысль выразить: " Что толку мне смотреть на план выполнеия запроса, если у меня в таблицах макс. 5 записей (см. п.1) и никакой информации об индексах?" ЗЫ Извини, что обидел тебя своими " теоретическими умствованиями ", но неплохо было бы сначала воспроизвести все условия задачи, а уж потом о конкретике ратовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 13:27:36 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
Table scan для второй таблице вполне оправдан, т.к. в условии используется функция COALESCE(). Для преодоления такой несправедливости можно попробовать ввести добавочное поле-флаг: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. ЗЫ Возможно , это улучшит дело, но мой план запроса - в обеих случаях Table scan. К тому же селективность индекса по полю-признаку мала, так что и на больших объемах оптимизатор скорее всего не будет его использовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 13:54:04 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
2 Jimmy Ну извини, что обидел насчёт плана. Но просто там невооружённым глазом видно, что скан будет - слева функция. Из такой ситуации выход только индекс на функцию. Или доп. поле, как ты сделал. А селективность зависит от того сколько там NULLов будет. Однако вариант с доп.полями не очень хорош, потому как ORы сразу портят всю малину. Да и прикинь сколько нужно вариантов перебрать - полей-то несколько сравнивается. Вот с likeом очень хорошо получается, как я написал. Но только в одну сторону... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 14:16:12 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
Ну я бы еще попробовал увеличить селективность индекса путем создания составного: create index idx_f2_is_null on test1 (f2,is_null) Но это к сожалению все, что я могу "родить". ЗЫ Без обид. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 14:21:43 |
|
||
|
WHERE с переменным числом условий
|
|||
|---|---|---|---|
|
#18+
я что-то отвлёкся :) Такое поле {0,1} не очень-то нужно - MSSQL превосходно справляется с индексированием по NULLам, и запросы оптимизирует с учётом их статистики, вот у Оракла, там есть с этим проблемы, там по NULLам всегда скан идёт (если не вру :)). Надо просто сделать так, что NULL в одном поле равен любому значению в соотвествующем. Это вот достигается или likeом с % или исключением этого условия для этих строк. Или ещё чем-то. Вот чем? Тут хотя бы знать даже, что это невозможно, чтоб не мучиться, а успокоиться. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2002, 14:46:27 |
|
||
|
|

start [/forum/topic.php?fid=46&tid=1820187]: |
0ms |
get settings: |
7ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
49ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
43ms |
get tp. blocked users: |
1ms |
| others: | 240ms |
| total: | 369ms |

| 0 / 0 |
