powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Объясните мне дураку (почему виснет запрос)
25 сообщений из 27, страница 1 из 2
Объясните мне дураку (почему виснет запрос)
    #32299121
Альберт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Объясните мне дураку, в чем проблема

запрос
---------------------------
SELECT MY_AUTHORS.*
FROM MY_AUTHORS
WHERE [код] in (select distinct author_code from dogovor);
---------------------------
отрабатывает без проблем, все чудненько, а вот запрос
---------------------------
SELECT MY_AUTHORS.*
FROM MY_AUTHORS
WHERE [код] not in (select distinct author_code from dogovor);
---------------------------
отрабатывает тоже быстро, но при перемещении, например, к последней записи виснет минуты на три.
поле [код] в my_authors ключевое, а в таблице dogovor поле author_code
входит в составной ключ из 3-х полей, иначе невозможно.
Всего порядка 2000 записей, 500 из них отбираются в 1-м запросе, остальные 1500 - во втором (цифры примерные).
Ни чего не понимаю, почему такие тормоза, может кто вразумит?
Был бы очень благодарен, а то юзеры орут просто.
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299134
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) ИМХО, distinct - лишнее
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299135
Альберт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
---------------------
1) ИМХО, distinct - лишнее
---------------------
не катит, пробовал и без него, таже байда
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299142
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не. Это, в принципе, лишнее. В данном случае. На производительность не влияет.
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299144
Альберт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Даже если это убрать, мне от этого не легче. Вот в чем вся проблема то
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299145
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почти оффтопик.
Размышления на тему.
Нижеприведенные размышления могут не совпадать с реальными фактами.
Все персонажи вымышленны.
Ни одно живое существо в ходе размышлений не пострадало.

Почему тормозит? Ну сам подумай. Представь себя на месте Джета. Чего тебе надо сделать во втором запросе:
1) Выбрать первую запись из таблицы Мои_авторы
2) Сравнить код этой записи со ВСЕМИ кодами из вложенного селекта.
3) И только в том случае, если он не равен ни одной записи в пункте 2 - добавить в конечную выборку.
4) Перейти на следущую запись.
5) GoTo п.2

При переходе на последнюю запсиь тормозит из-за замечательной, а иногда очень мерзкой, особенности Аксеса - рассчитывать и выводить только тот результат, который умещается на экран. И только при переходе на последнюю запись у тебя рассчитывается ВЕСЬ запрос сразу.
Может быть эту особенность можно отключить. Как - не знаю.
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299149
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К последнему предложению последнего поста:
Но в любом случае - это не поможет. Просто ты сразу будешь ждать 3 минуты
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299152
Альберт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Даже и не знаю радоваться ли тому что ты мне сейчас написал или нет.....
Просто никогда даже и не задумывался, что, работая с 2000 записей плюс 10000 во вложенном запросе, запрос так может затормозить. Никогда не было ничего подобного ни в оракле ни в SQLсервере ни даже в dbf-нике.
От сюда вытекает другой вопрос. Рас уж аксессовский джет так ЗАМЕЧАТЕЛЬНО работает, то может ему можно предложить другой вариант запроса, от которого он ни за что не отказался бы и отработал бы ну скажем секунда за 10(ну никак не дольше)????????
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299156
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проверка времени выполнения всего запроса - тыркаешь экспорт в ёксель и засекаешь время. В итоге - почти чистое время выполнения запроса.
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299161
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Смоделировал ситуацию - такая же жопа.
Блин, чувствую, что решение простое до невозможности, но никак не придумаю.
Ладно, я пошел думать.
Кто первый догадается/вспомнит, тот почти Гетц.
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299163
Альберт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
:-)
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299169
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
/topic/47988&hl=showplan#333175\r
\r
Посмотри еще тут.\r
з.ы. Я продолжаю думать.
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299176
Paul Chabinsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще использование подзапроса как параметра для ключевого слова IN последнее дело и крайний вариант, обходить подобные ситуации я бы посоветовал с помощью джоина, например:

Код: plaintext
1.
2.
3.
SELECT MY_AUTHORS.* 
FROM MY_AUTHORS 
WHERE [код] in (select distinct author_code from dogovor);

можно представить так:
Код: plaintext
1.
2.
3.
SELECT a.*
FROM MY_AUTHORS a, (select distinct author_code from dogovor) b
WHERE a.[код] = b.author_code


Для того чтоб найти строчки из MY_AUTHORS не входящие в подзапрос - (select distinct author_code from dogovor), нужно сначало сделать аутер джоин, группируя по [код], выбрать count. Потом результать заджоинить с самой таблицей MY_AUTHORS, и выбрать только те строчки коунт которых равен нулю...

Если не понятно что я написал то завтра днем напишу примерный запрос :)
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299177
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1:
Вот функция:
Код: 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.
Function aaa()
  Dim t As Double
  Dim i As Long
  Dim rs As Recordset
  
  t = Timer
  For i =  1  To  20 
    Set rs = CurrentDb.OpenRecordset( "SELECT * FROM Table1 WHERE Table1.Field1 In (select Field2 from Table2);" )
    rs.MoveLast: rs.Close: Set rs = Nothing
  Next i
  Debug.Print Timer - t
  
  t = Timer
  For i =  1  To  20 
    Set rs = CurrentDb.OpenRecordset( "SELECT * FROM Table1 WHERE Table1.Field1 Not In (select Field2 from Table2);" )
    rs.MoveLast: rs.Close: Set rs = Nothing
  Next i
  Debug.Print Timer - t
  
  t = Timer
  For i =  1  To  20 
    Set rs = CurrentDb.OpenRecordset( "SELECT * FROM Table1 LEFT JOIN Table2 ON Table1.Field1 = Table2.Field2 WHERE (Not (Table2.Field2) Is Null);" )
    rs.MoveLast: rs.Close: Set rs = Nothing
  Next i
  Debug.Print Timer - t
  
  t = Timer
  For i =  1  To  20 
    Set rs = CurrentDb.OpenRecordset( "SELECT * FROM Table1 LEFT JOIN Table2 ON Table1.Field1 = Table2.Field2 WHERE (Table2.Field2) Is Null;" )
    rs.MoveLast: rs.Close: Set rs = Nothing
  Next i
  Debug.Print Timer - t
End Function


А вот результаты (таблица 1 - 2600 записей, 1-я и 3-я выборки дают 500, 2 и 4-я 2100 записей):
Код: plaintext
1.
2.
3.
4.
?aaa
  0 , 152249999999185  
  6 , 99343750000116  
  0 , 151874999995925  
  0 , 189375000001746  


Почему - не знаю. Скорее всего, имеет смысл поиграть с индексами.

С удовольствием сам бы узнал почему при прочих равных left join работает быстрее, чем not in.
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299179
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Держи примерный кривой донельзя запрос:
Код: plaintext
1.
2.
SELECT MY_AUTHORS.*
FROM MY_AUTHORS LEFT JOIN all_Authors ON MY_AUTHORS.код = all_Authors.код
WHERE (((all_Authors.код) Is Null));


All_Authors - твой вложенный селект, где код - код автора.
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299183
Paul Chabinsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я тупанул насчет коунта... Спать уже хочица :) но Geo меня понял правильно.

2Geo

Быстрее работает потому что при использовании подзапроса в параметрах IN
на каждую строчку первой таблицы выполница селект из второй, а при лефт джоине подзапрос выполнится только один раз...
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299184
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Энштейн, куда пропал?
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299187
Альберт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Огромное спасибо, Темный, Geo... Кажется все отлично работает....
Сам, наверное, не допер бы :-)))
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299189
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А чего работает-то? Мое? Или Гиино? Мне уже интересно...
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299190
Альберт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Paul Chabinsky, тебе тоже спасибо. Правда новая незадача. Мой старый дряхлый запрос давал на 3 записи меньше. Может где-то нулевые данные?
Короче запустил запрос для сравнения этих 2-х запросов и все..... тишина, уже минут 20
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299191
Альберт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Темный, твой запрос совпадает с 4-м из тех, что дал geo, так что обоим спасибо, а с разным кол-вом записей разбирусь
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299192
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Paul Chabinsky
Быстрее работает потому что при использовании подзапроса в параметрах IN на каждую строчку первой таблицы выполница селект из второй, а при лефт джоине подзапрос выполнится только один раз...

Боюсь, что все не так просто, как тебе кажется. Если смотреть по моему тесту, то:

Во-первых, первый и третий варианты отработались с равной скоростью.

Во-вторых, откуда взялась такая разница между первым и вторым вариантом. Ведь казалось бы, если посмотреть в вариант 1, время на отбор 500 записей, подходящих под условие, должно быть намного меньшим (нашли первую подходящую запись в подчиненном запросе, дальше смотреть не надо), чем отсеять остальные 2100 (для каждой из этих записей, с твоих слов, полностью выполнить подчиненный запрос). Отсюда следует, что вот так, на пальцах рассуждать об работе запросов в акцессе немного "некрасиво" что-ли...

---

Полистал 1-й том Гетца об использовании IN, увидел только, что "подобные запросы проще для понимания но обычно работают медленнее". И все...
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299194
Альберт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Блин, чудак я, не туда смотрел, все совпадает, и там и там по 1387. Так что все ОК. Есть правда одно маааааленькое отличие - первый (мой) запрос выполняется за 3 минуты, а второй (ваш) - за доли секунды. Вот в общем-то и все...Еще раз фенька ю. До связи!
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299308
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Geo
>Полистал 1-й том Гетца об использовании IN, увидел только, что "подобные запросы проще для понимания но обычно работают медленнее". И все...

Где видел не помню, возможна инфа верна только для MS SQL.
IN разбиваються на Where ...OR..., при достижении опредленного кoл-ва OR - строится темп-таблица к которой джоинится главная. Легко построить темп-таблицу по всем записям, и трудновато по не существующим (лишнии операции).
Таким образом, самое оптимальное не нагружать бедный джет лишними IN'ами, а сразу использовать соответсвующие джоины либо Where ...OR...

==
Про индексы у Альберта никто не спросил - я буду первым :)
Альберт - индексы есть? Какие? Где?
...
Рейтинг: 0 / 0
Объясните мне дураку (почему виснет запрос)
    #32299329
Саша 594
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
From:

http://www.sql-server-performance.com/transact_sql.asp


It is fairly common request to write a Transact-SQL query to to compare a parent table and a child table and find out if there are any parent records that don't have a match in the child table. Generally, there are three ways this can be done:

Using a NOT EXISTS

SELECT a.hdr_key
FROM hdr_tbl a
WHERE NOT EXISTS (SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key)

Using a Left Join

SELECT a.hdr_key
FROM hdr_tbl a
LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key
WHERE b.hdr_key IS NULL

Using a NOT IN

SELECT hdr_key
FROM hdr_tbl
WHERE hdr_key NOT IN (SELECT hdr_key FROM dtl_tbl)

In each case, the above query will return identical results. But, which of these three variations of the same query produces the best performance? Assuming everything else is equal, the best performing version through the worst performing version will be from top to bottom, as displayed above. In other words, the NOT EXISTS variation of this query is generally the most efficient.

I say generally, because the indexes found on the tables, along with the number of rows in each table, can influence the results. If you are not sure which variation to try yourself, you can try them all and see which produces the best results in your particular circumstances. [7.0, 2000] Added 3-29-2002
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Объясните мне дураку (почему виснет запрос)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]