Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Объясните мне дураку (почему виснет запрос) / 25 сообщений из 27, страница 1 из 2
20.10.2003, 21:57
    #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
20.10.2003, 22:43
    #32299134
Темный
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
1) ИМХО, distinct - лишнее
...
Рейтинг: 0 / 0
20.10.2003, 22:46
    #32299135
Альберт
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
---------------------
1) ИМХО, distinct - лишнее
---------------------
не катит, пробовал и без него, таже байда
...
Рейтинг: 0 / 0
20.10.2003, 22:51
    #32299142
Темный
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
Не. Это, в принципе, лишнее. В данном случае. На производительность не влияет.
...
Рейтинг: 0 / 0
20.10.2003, 22:57
    #32299144
Альберт
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
Даже если это убрать, мне от этого не легче. Вот в чем вся проблема то
...
Рейтинг: 0 / 0
20.10.2003, 23:01
    #32299145
Темный
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
Почти оффтопик.
Размышления на тему.
Нижеприведенные размышления могут не совпадать с реальными фактами.
Все персонажи вымышленны.
Ни одно живое существо в ходе размышлений не пострадало.

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

При переходе на последнюю запсиь тормозит из-за замечательной, а иногда очень мерзкой, особенности Аксеса - рассчитывать и выводить только тот результат, который умещается на экран. И только при переходе на последнюю запись у тебя рассчитывается ВЕСЬ запрос сразу.
Может быть эту особенность можно отключить. Как - не знаю.
...
Рейтинг: 0 / 0
20.10.2003, 23:07
    #32299149
Темный
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
К последнему предложению последнего поста:
Но в любом случае - это не поможет. Просто ты сразу будешь ждать 3 минуты
...
Рейтинг: 0 / 0
20.10.2003, 23:13
    #32299152
Альберт
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
Даже и не знаю радоваться ли тому что ты мне сейчас написал или нет.....
Просто никогда даже и не задумывался, что, работая с 2000 записей плюс 10000 во вложенном запросе, запрос так может затормозить. Никогда не было ничего подобного ни в оракле ни в SQLсервере ни даже в dbf-нике.
От сюда вытекает другой вопрос. Рас уж аксессовский джет так ЗАМЕЧАТЕЛЬНО работает, то может ему можно предложить другой вариант запроса, от которого он ни за что не отказался бы и отработал бы ну скажем секунда за 10(ну никак не дольше)????????
...
Рейтинг: 0 / 0
20.10.2003, 23:14
    #32299156
Темный
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
Проверка времени выполнения всего запроса - тыркаешь экспорт в ёксель и засекаешь время. В итоге - почти чистое время выполнения запроса.
...
Рейтинг: 0 / 0
20.10.2003, 23:24
    #32299161
Темный
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
Смоделировал ситуацию - такая же жопа.
Блин, чувствую, что решение простое до невозможности, но никак не придумаю.
Ладно, я пошел думать.
Кто первый догадается/вспомнит, тот почти Гетц.
...
Рейтинг: 0 / 0
20.10.2003, 23:28
    #32299163
Альберт
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
:-)
...
Рейтинг: 0 / 0
20.10.2003, 23:43
    #32299169
Темный
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
/topic/47988&hl=showplan#333175\r
\r
Посмотри еще тут.\r
з.ы. Я продолжаю думать.
...
Рейтинг: 0 / 0
21.10.2003, 00:02
    #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
21.10.2003, 00:03
    #32299177
Geo
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
21.10.2003, 00:08
    #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
21.10.2003, 00:19
    #32299183
Paul Chabinsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните мне дураку (почему виснет запрос)
Я тупанул насчет коунта... Спать уже хочица :) но Geo меня понял правильно.

2Geo

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

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

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

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

---

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

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

==
Про индексы у Альберта никто не спросил - я буду первым :)
Альберт - индексы есть? Какие? Где?
...
Рейтинг: 0 / 0
21.10.2003, 09:47
    #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
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Объясните мне дураку (почему виснет запрос) / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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