Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности

Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
|
10.05.2001, 13:22
|
|||
|---|---|---|---|
|
|||
JOIN и фильтрация записей ? |
|||
|
#18+
Вопросы такие: 1) Правильно ли что при использовании нескольких JOIN соединение таблиц идет последовательно с учетом, записей которые получились при предыдущим JOIN ? И имеет ли смысл в таком случае уже в первых JOIN указывать условие для фильтрации записей чтобы в соединении уже сразу участвовало меньше записей, а не фильтровать их потом в WHERE ? Пример : @LAgr_id int = NULL, @AgrNum varchar(30) = NULL, @Cust_id int = NULL, @Cust_name varchar(100) =NULL, @Manager varchar(25) = NULL, @PaySDate datetime = NULL, @PayEDate datetime = NULL, @PrSDate datetime = NULL, @PrEDate datetime = NULL, @Status tinyint = NULL, @Type tinyint = NULL, @Curr char(3) = NULL SELECT ..... FROM LInvoices i INNER JOIN LInvoicesStatus si ON i.Status=si.Status INNER JOIN LInvoicesType it ON i.Type=it.Type and (@Type IS NULL or i.Type=@type) INNER JOIN LAgreements a ON i.Lagr_id = a.LAgr_id and i.Lagr_id=@Lagr_id INNER JOIN LAgrStatus sa ON a.Status = sa.Status INNER JOIN customers c ON i.Cust_id = c.Cust_id WHERE (@Manager IS NULL or a.User_id=@Manager) and (@PrSDate IS NULL or i.PrintDate>=@PrSDate) and (@PrEDate IS NULL or i.PrintDate<=@PrEDate) and (@PaySDate IS NULL or i.PrintDate>=@PaySDate) and (@PayEDate IS NULL or i.PrintDate<=@PayEDate) and (@Curr IS NULL or i.Curr=@Curr) and ((@Status IS NULL and i.Status<10 and i.Status>0) or (@Status IN (5,10,1) and i.Status=@Status) or (@Status=2 and i.Status IN (2,3,4)) or (@Status=0 and i.Status IN (1,2,3,4))) таблица LInvoices самая большая, но если выбрать записи с соответствующим @Type и @Status то останеться не так много записей, и получаеться что в соединеии с таблицами LAgreements и customers будет участвовать только 10% записей из LInvoices, а не все и потом фильтрация всей получившийся в результате JOIN таблицы выражением WHERE. Правильно ли это ? 2)Проблема в том что когда выражение and ((@Status IS NULL and i.Status<10 and i.Status>0) or (@Status IN (5,10,1) and i.Status=@Status) or (@Status=2 and i.Status IN (2,3,4)) or (@Status=0 and i.Status IN (1,2,3,4))) добавляеться к JOIN то при значениях @Status=2 или @Status=0 проискодит не фильтрация а возвращение дополнительных строк, тоесть возвращаються несколько строк для каждой строки из таблицы, три строки со статусами 2,3,4 или четыре со стстусами 1,2,3,4 соответственно. Что не правильно в данном синтаксисе .... в WHERE все работает как задомано, при @Status=2 возращаються строки у которых статус 2, 3, или 4. ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
11.05.2001, 05:40
|
|||
|---|---|---|---|
|
|||
JOIN и фильтрация записей ? |
|||
|
#18+
1. Оптимизатор запросов работает так, что может перевернуть с ног на голову порядок объединения и фильтрации таблиц в запросе. Поэтому не гарантируется, что фильтрация по LInvoices выполнится первой. См. Query Plan. 2. Написание запроса неоптимально с точки зрения использования индексов и Foreign Keys. Условия OR в WHERE переключают просмотр таблиц в Table Scan. Поэтому все таблицы будут всегда просматриваться полностью. 3. Пункт 2 вполне верен. Для фильтрации необходимо условия заносить во WHERE. ОСОБЕННО если в условии фигурируют данные только одной таблицы (и локальных переменных). Перенос в JOIN критичен при условии (LEFT,RIGHT) JOIN. 4. Если уж необходимо делать выборку одним запросом, может сформирровать строку запроса динамически в зависимости от значаний лок. переменных, убрав тем самым OR, а потом выполнить EXECUTE (SQL). 5. Я могу в чем-то ошибаться, поскольку работаю с MSSQL 6.5, поэтому изучайте Query Plan. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
11.05.2001, 15:30
|
|||
|---|---|---|---|
|
|||
JOIN и фильтрация записей ? |
|||
|
#18+
Начал изучать QueryPalan но ничего не понимаю ! Где можно посмотреть в каком режиме (сканирование и т.д.)просматриваеться таблица ? Как получить Query Plan в зависимости от входных данных сохраненной процедуры (надо вначале задекларировать все параметры а потом присвоить им значения или QueryPalan всегда одинаковый для всех входных данных)? Например если в сохраненной процедуре есть IF @Parametr=2 SELECT ... ELSE IF @Parametr2=3 SELECT и дальше в том же духе ... ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
14.05.2001, 10:58
|
|||
|---|---|---|---|
|
|||
JOIN и фильтрация записей ? |
|||
|
#18+
Тоесть как я понял использование конструкции (@PrEDate IS NULL or i.PrintDate<=@PrEDate) как в WHERE так и в JOIN ON ... или нескольких таких конструкций в одном запросе для нескольких полей и таблиц, переводит каждую из таблиц к которой относиться это условие в режим просмотра всех записей , что сильно снизит производительность ? А как тогда обтимальнее выполнять фильтрацию ? Для каждого параметра фильтрации поля выполнять IF NOT @PrEDate IS NULL SELECT ... ELSE IF ... ? но в этом случае будет куча таких IF если у меня например 5-6 параметров фильтрации и они могут присутствовать в любой комбинации ... Может выполнять фильтрацию используя свойство Filter для DataSet будет обтимальнее ? Или всетаки лучше использовать передачу всех параметров фильтрации в SP ? (я работаю с MSSQL7 и ADO+Delphi5) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|

start [/forum/search_topic.php?author=SergeyR&author_mode=last_posts&do_search=1]: |
0ms |
get settings: |
12ms |
get forum list: |
15ms |
get settings: |
10ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
30ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
37ms |
get tp. blocked users: |
1ms |
| others: | 666ms |
| total: | 805ms |

| 0 / 0 |
