|
|
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Посоветуйте, как бы оптимизировать запросы. Есть табличка table1 (id, name), и есть подчиненная табличка table2 (id, owner_id, code) В табличке table2 может быть множество записей для одного owner_id, который ссылается на запись в table1. Задача, посчитать кол-во записей в table1, для которых существуют в table2 записи с code=5 и code=8 одновременно . Итоговый запрос такой: Код: plaintext 1. 2. 3. 4. 5. 6. Хочется избавиться от exists... но как? Вообще запрос строится динамически, и кол-во этих exists может быть любое. Помогите мыслью плз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2008, 18:50 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2008, 19:02 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Ennor Tiegael беда в том, что условие отбора из table1 может быть любым, не только code=5 and code=8, а вообще любым (юзер пишет), т.е. например (code > 5 and code != 3) or code = 19 более того, если условие например not code=7, то это значит что выбрать записи из table1, для которых нет записи с code=7 в table2. Сейчас это отрабатывается как раз not exists(...) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2008, 19:19 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
select count(*) from table1 t1 where id in (select owner_id from table2 where (code > 5 and code != 3) or code = 19 ......) А можно вроде как вообще без table1, если с ссылками все в порядке select count(distinct owner_id) from table2 where (code > 5 and code != 3) or code = 19 ...... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2008, 20:20 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Ой пардон. Виноват Не до конца в условие задачи прочитал ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2008, 20:23 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Ну если условия совсем произвольные, то никак - самый быстрый вариант как раз через (not) exists, и он же единственный более-менее формализуемый. Интересно, правда, посмотреть, как вы будете реализовывать запрос пользователя вида "code < 7, и чтобы в t2 присутствовали все возможные варианты" . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2008, 00:53 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Запросы строятся по формулам вида: q6(code=4 or code=5 or code=6) and q5=1 and q1=7 and q999 или q999 and (q500 or (q11 and not q129)) и т.д. Сами эти формулы абсолютно произвольны и зависят от проектов, и пишутся юзерами. вот например реальный запрос построеный автоматом по первой формуле: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. а вот запрос по второй формуле из примера: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. вот такая вот херомантия :) в принципе, всё конечно работает, но в табличке Answers каждый день становится на 100...500 тысяч записей больше, и постепенно всё замедляется. в Answers есть уникальный индекс по RespondentCallID + QuestionNumber + AnswerCode, но, почему-то сервер не всегда делает по нему index seek при выполнении exists, т.е. например один exists пользует index scan, а остальные index seek, и на этот scan уходит 27% времени. Никак не удатся заставить _всегда_ пользовать index seek. беда :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2008, 13:41 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Alexey Triznoв Answers есть уникальный индекс по RespondentCallID + QuestionNumber + AnswerCodeНе пробовали его кластерным сделать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2008, 14:54 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
пробовал, ничего особо не меняется, всё равно сканы проскакивают ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2008, 15:02 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Я так и подумал что речь идет про анализ чего-то типа звонков и т.п. Вообще я бы пересмотрел саму бизнес логику такого анализа и соответственно пути решения. Т.е. делал бы анализ не на основе таких сложных многокритериальных запросов к таблице table2, а к другой таблице(источнику данных) типа промежуточных(сводных) итогов и результатов, которую формировать на основе table2. Или, если задача еще серьезнее, то можно и OLAP задействовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2008, 15:03 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Я имел ввиду примерно следующее. Завести группы фильтрации по вашим проектам. Завести таблицы с итогами фильтрации по группам. Задать и реализовать правила расчета и актуализации данных в таблицах итогов(по расписанию, по триггерам и т.п.) Выборки для анализа вести уже по таблицам итогов, получая группы и количество групп, в которые входит id из table1. Если речь идет только о вхождении в несколько групп, то можно вообще таблицу итогов с 2 колонками вести типа group_id, owner_id Пользователь при запросе задает не условия, а список групп, в которые одновременно должен входить owner_id. Дальше все просто. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2008, 18:53 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Не пройдет такое... это база для хранения результатов телефонных опросов, т.е. здоровенные анкеты. Они постоянно меняются, куча проектов разных со своими анкетами, и эти счетчики должны считаться в реальном времени по реальным данным, иначе смысла вообще не имеет. И что именно считать - решаю не я :( Сами они придумывают. И главное - все считается по реальным данным, в real time, пока идет сбор данных. И после сбора тоже. По ходу дела делаются выгрузки результатов опять же с такими же фильтрами, на основе тех же формул. Кол-во вопросов в анкете иногда ужасает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2008, 13:05 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Я понял, интересная задачка. Но все равно в реальном времени можно считать в промежуточные таблицы итогов, если заранее известны хотя бы часть условий(знают же те, кто составляет анкету, что они хотят получить в итоге. хотя бы начальные цели). Если условие(в вашем случае совокупность условий) по проекту добавляется в реальном времени, то тут же пересчитывать итоги по нему. Мне кажется, что все равно такой подход будет быстрее, чем каждый раз по пересчитывать заново от всего объема, да еще и сложным неоптимизированным запросом с точки зрения сервера. Если все так действительно серьезно у Вас с объемами, то на "голом" SQL без применения подобных способов(а лучше вообще средств многомерных баз и анализа и т.п.) нормально решить не получиться. Можно конечно сервак наращивать до безобразия и т.п., но не предназначен сервер OLTP для решения подобных задач. По сути, если у Вас условия запросов придумываются в реальном времени, то Вы саму многомерную модель анализа строите(меняете) в реальном времени и еще результаты от нее хотите получать в реальном времени. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2008, 19:59 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Да, я постоянно думаю чего бы такого добавить в структуру, чтобы не проходить по основным данным, но вот что - никак не придумывается. В принципе, при сохранении каждого интервью в базу я могу в памяти по нему просчитать все заданные формулы, и понять, какие формулы сработали, и соответственно куда-то записать результаты. Т.е. например для каждого счетчика (в нем указана формула для расчета значения) хранить список ID звонков, для которых он сработал, и тогда значение счетчика будет равно кол-ву элементов в этом списке. С другой стороны, можно вообще не иметь такого списка, а просто при записи интервью просто увеличивать на 1 значение всех счетчиков, которые затронуты, но, так нельзя, т.к. расчет может фильтроваться по дате звонка и юзеру, который его сделал. Сл-но надо иметь именно табличку вида id, call_id, call_date, user_id, для каждого счетчика. Правильно размышляю, или опять тупик? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2008, 12:57 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Можно попробывать закачать промежуточный результат в temp таблицу а потом к ней применить полное условие. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2008, 14:05 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
_модМожно попробывать закачать промежуточный результат в temp таблицу а потом к ней применить полное условие. я бы тоже использовал temp. закачал бы в нее Код: plaintext 1. по получившейся небольшой табличке и запрос с кучей exists быстро отработает ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2008, 17:44 |
|
||
|
Посоветуйте алгоритм построения запроса (замена exists(select...))
|
|||
|---|---|---|---|
|
#18+
Alexey Triznoвот такая вот херомантия :) в принципе, всё конечно работает, но в табличке Answers каждый день становится на 100...500 тысяч записей больше, и постепенно всё замедляется. Можно попробовать добавлять подзапросы вместо EXIST-ов. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. но для этого скорее всего придется переделывать индексы. Alexey Triznoв Answers есть уникальный индекс по RespondentCallID + QuestionNumber + AnswerCode, но, почему-то сервер не всегда делает по нему index seek при выполнении exists, т.е. например один exists пользует index scan, а остальные index seek, и на этот scan уходит 27% времени. Никак не удатся заставить _всегда_ пользовать index seek. беда :(что за поле: AnswerCode? в запросах его нету. Может дело в том, что иногда сервер не осиливает поиск по части индекса (2 поля), если значени есть в трех полях? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2008, 13:21 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=35399671&tid=1543786]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
153ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
40ms |
get tp. blocked users: |
1ms |
| others: | 199ms |
| total: | 429ms |

| 0 / 0 |
