Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите с запросом / 25 сообщений из 35, страница 1 из 2
18.10.2013, 02:48:46
    #38432184
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Всем привет.

Есть таблица:
Код: sql
1.
2.
3.
4.
5.
CREATE TABLE INC_STATE (
ADDR SMALLINT NOT NULL, 
ID INTEGER NOT NULL, 
VAL INTEGER NOT NULL, 
CONSTRAINT UNQ_ADDR_ID UNIQUE (ADDR, ID));


Из таблицы INC_STATE нужно определить все ADDR для которых существуют записи, в которых ID = 200, а VAL = 0 и ID = 201, а VAL = 0.

Если бы было одно из условий, я бы сделал:
Код: sql
1.
SELECT DISTINCT ADDR FROM INC_STATE WHERE (ID = 200 AND VAL = 0) OR (ID = 201 AND VAL = 0);


Но нужно оба, а
Код: sql
1.
SELECT DISTINCT ADDR FROM INC_STATE WHERE (ID = 200 AND VAL = 0) AND (ID = 201 AND VAL = 0);

по понятным причинам не работает.

Единственное что пришло в голову это вот такой изврат:
Код: sql
1.
2.
3.
4.
5.
SELECT DISTINCT ADDR FROM INC_STATE d 
WHERE 
     EXISTS (SELECT ADDR FROM INC_STATE e WHERE (e.ID = 200 AND e.VAL = 0) AND e.ADDR = d.ADDR)
     AND 
     EXISTS (SELECT ADDR FROM INC_STATE e WHERE (e.ID = 201 AND e.VAL = 0) AND e.ADDR = d.ADDR);


Так работает, но чувствую, что должно быть более красивое решение.

Может, кто-то подскажет?
...
Рейтинг: 0 / 0
18.10.2013, 06:09:27
    #38432209
Tactical Nuclear Penguin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
как-нибудь так

Код: sql
1.
2.
3.
SELECT DISTINCT ADDR FROM INC_STATE d 
JOIN INC_STATE e ON e.ADDR = d.ADDR AND e.ID = 200 AND e.VAL = 0
WHERE d.ID = 201 AND d.VAL = 0
...
Рейтинг: 0 / 0
18.10.2013, 06:25:28
    #38432211
m_Sla
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Код: sql
1.
2.
3.
SELECT a.ADDR FROM INC_STATE a 
JOIN INC_STATE b ON a.ADDR=b.ADDR 
WHERE a.ID = 200 AND a.VAL = 0 AND b.ID = 201 AND b.VAL = 0
...
Рейтинг: 0 / 0
18.10.2013, 10:24:59
    #38432386
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
можно и вот так

Код: sql
1.
2.
3.
4.
5.
SELECT ADDR 
FROM INC_STATE
WHERE VAL = 0 AND ID IN (200, 201)
GROUP BY ADDR
HAVING COUNT(DISTINCT ID) = 2
...
Рейтинг: 0 / 0
18.10.2013, 20:46:49
    #38433477
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Tactical Nuclear Penguinкак-нибудь так

Код: sql
1.
2.
3.
SELECT DISTINCT ADDR FROM INC_STATE d 
JOIN INC_STATE e ON e.ADDR = d.ADDR AND e.ID = 200 AND e.VAL = 0
WHERE d.ID = 201 AND d.VAL = 0

Код: sql
1.
2.
3.
4.
5.
Statement failed, SQLSTATE = 42702
Dynamic SQL Error
-SQL error code = -204
-Ambiguous field name between table INC_STATE and table INC_STATE
-ADDR
...
Рейтинг: 0 / 0
18.10.2013, 20:47:45
    #38433478
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
m_Sla
Код: sql
1.
2.
3.
SELECT a.ADDR FROM INC_STATE a 
JOIN INC_STATE b ON a.ADDR=b.ADDR 
WHERE a.ID = 200 AND a.VAL = 0 AND b.ID = 201 AND b.VAL = 0

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
PLAN JOIN (A NATURAL, B INDEX (UNQ_ADDR_ID))

   ADDR
=======
     17
     16
      0
     -1

Current memory = 616364
Delta memory = -4100
Max memory = 801464
Elapsed time= 0.00 sec
Buffers = 75
Reads = 0
Writes 0
Fetches = 1329
...
Рейтинг: 0 / 0
18.10.2013, 20:53:11
    #38433484
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Симонов Денисможно и вот так

Код: sql
1.
2.
3.
4.
5.
SELECT ADDR 
FROM INC_STATE
WHERE VAL = 0 AND ID IN (200, 201)
GROUP BY ADDR
HAVING COUNT(DISTINCT ID) = 2

Спасибо. Похоже, что если бы к моему варианту с ИЛИ дописать
Код: sql
1.
GROUP BY ADDR HAVING COUNT(DISTINCT ID) = 2

получилось бы тоже самое.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
SELECT DISTINCT ADDR FROM INC_STATE WHERE (ID = 200 AND VAL = 0) OR (ID = 201 AND VAL = 0) GROUP BY ADDR HAVING COUNT(DISTINCT ID) = 2;


PLAN (INC_STATE ORDER UNQ_ADDR_ID)

   ADDR
=======
     -1
      0
     16
     17

Current memory = 617660
Delta memory = 784
Max memory = 801464
Elapsed time= 0.00 sec
Buffers = 75
Reads = 0
Writes 0
Fetches = 1930

Планы один в один.
...
Рейтинг: 0 / 0
18.10.2013, 20:59:31
    #38433490
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Спасибо всем ответившим. И еще вопрос. А с точки зрения плана какой из запросов быстрее.

План моего запроса (походу самый неудачный)
Код: sql
1.
2.
3.
PLAN (E INDEX (UNQ_ADDR_ID))
PLAN (E INDEX (UNQ_ADDR_ID))
PLAN SORT ((D NATURAL))



План запроса m_Sla
Код: sql
1.
PLAN JOIN (A NATURAL, B INDEX (UNQ_ADDR_ID))



И план запроса Симонова Дениса
Код: sql
1.
PLAN (INC_STATE ORDER UNQ_ADDR_ID)



Сточки зрения производительности, чем лучше пользоваться?
...
Рейтинг: 0 / 0
18.10.2013, 21:05:54
    #38433495
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
agodaBuffers = 75
ну ты крут, конечно. Вообще ничего не читал про ФБ классик? Ну хоть это прочитай
http://www.ibase.ru/devinfo/optimize.htm
...
Рейтинг: 0 / 0
18.10.2013, 22:30:02
    #38433556
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
agodaСимонов Денисможно и вот так

Код: sql
1.
2.
3.
4.
5.
SELECT ADDR 
FROM INC_STATE
WHERE VAL = 0 AND ID IN (200, 201)
GROUP BY ADDR
HAVING COUNT(DISTINCT ID) = 2

Спасибо. Похоже, что если бы к моему варианту с ИЛИ дописать
Код: sql
1.
GROUP BY ADDR HAVING COUNT(DISTINCT ID) = 2

получилось бы тоже самое.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
SELECT DISTINCT ADDR FROM INC_STATE WHERE (ID = 200 AND VAL = 0) OR (ID = 201 AND VAL = 0) GROUP BY ADDR HAVING COUNT(DISTINCT ID) = 2;


PLAN (INC_STATE ORDER UNQ_ADDR_ID)

   ADDR
=======
     -1
      0
     16
     17

Current memory = 617660
Delta memory = 784
Max memory = 801464
Elapsed time= 0.00 sec
Buffers = 75
Reads = 0
Writes 0
Fetches = 1930

Планы один в один.



DISTINCT тут лишний, т.к. GROUP BY и так удалит дубликаты. Условия что с IN что с OR эквивалентны. Если не хочешь использовать IN, то лучше вот так

Код: sql
1.
2.
3.
4.
5.
SELECT ADDR 
FROM INC_STATE 
WHERE VAL = 0 AND (ID = 200 OR ID = 201) 
GROUP BY ADDR 
HAVING COUNT(DISTINCT ID) = 2;



agodaPLAN (INC_STATE ORDER UNQ_ADDR_ID)

Хм. Я думал будет PLAN (INC_STATE ORDER UNQ_ADDR_ID INDEX (UNQ_ADDR_ID, UNQ_ADDR_ID))
...
Рейтинг: 0 / 0
18.10.2013, 22:36:46
    #38433559
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
kdvagodaBuffers = 75
ну ты крут, конечно. Вообще ничего не читал про ФБ классик? Ну хоть это прочитай
http://www.ibase.ru/devinfo/optimize.htm Спасибо, статья отличная. Много классных инструментов. Но на что намекает Buffers = 75 я там не нашел. Можете ткнуть носом?
...
Рейтинг: 0 / 0
18.10.2013, 22:41:42
    #38433565
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Симонов ДенисХм. Я думал будет PLAN (INC_STATE ORDER UNQ_ADDR_ID INDEX (UNQ_ADDR_ID, UNQ_ADDR_ID))

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SQL> SELECT ADDR FROM INC_STATE WHERE VAL = 0 AND ID IN (200, 201) GROUP BY ADDR HAVING COUNT(DISTINCT ID) = 2;

PLAN (INC_STATE ORDER UNQ_ADDR_ID)

   ADDR
=======
     -1
      0
     16
     17

Current memory = 1581048
Delta memory = -8
Max memory = 1712464
Elapsed time= 0.00 sec
Buffers = 75
Reads = 0
Writes 0
Fetches = 1930

Еще раз проверил
...
Рейтинг: 0 / 0
18.10.2013, 22:42:23
    #38433567
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
agoda,

увеличить бы надо до 256-2048. Я бы поставил 1024 для начала
...
Рейтинг: 0 / 0
18.10.2013, 22:45:51
    #38433570
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
agoda,

мне странно почему FB не задействовал сегмент индекса UNQ_ADDR_ID по полю ID
...
Рейтинг: 0 / 0
18.10.2013, 22:56:02
    #38433575
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
agoda Но на что намекает Buffers = 75 я там не нашел. Можете ткнуть носом?
раздел "Память", про кэш Классика. Рекомендую статьи, если они непонятны, вообще, любые, перечитывать по нескольку раз. Ничего стыдного в этом нет, я сам регулярно так делаю в отношении чужих (и своих) статей.
Кроме того, в этом разделе форума туча топиков на тему "классик кэш".

p.s. свою статью поправлю на эту тему.
...
Рейтинг: 0 / 0
18.10.2013, 22:58:06
    #38433578
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Симонов Денисмне странно почему FB не задействовал сегмент индекса UNQ_ADDR_ID по полю ID
потому что
ID IN (200, 201)
это
((ID = 200) or (ID = 201))

то есть, 2 скана индекса по OR, в то время как есть другие условия по AND.
...
Рейтинг: 0 / 0
18.10.2013, 23:10:21
    #38433586
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
kdv,

Только вот если создать отдельный индекс, то он почему-то будет задействован.

Код: sql
1.
CREATE INDEX IDX_ID ON INC_STATE (ID);



Код: sql
1.
2.
3.
4.
5.
SELECT ADDR 
FROM INC_STATE
WHERE VAL = 0 AND ID IN (200, 201)
GROUP BY ADDR
HAVING COUNT(DISTINCT ID) = 2



PLAN (INC_STATE ORDER UNQ_ADDR_ID INDEX (IDX_ID, IDX_ID))
...
Рейтинг: 0 / 0
18.10.2013, 23:11:54
    #38433587
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Симонов Денисagoda,

увеличить бы надо до 256-2048. Я бы поставил 1024 для началаСпасибо, этот намек я понял.
Сразу как-то не возникло ассоциаций между Buffers и DbCachePages.
Просто я тестю на домашней машине отдельные запросы, база нерабочая. На рабочей у меня 2048
...
Рейтинг: 0 / 0
18.10.2013, 23:17:00
    #38433592
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
agoda,
статью обновил. Стало понятнее? Если нет, прошу комментарии, буду редактировать до тех пор, пока не будет понятно даже начинающим.
...
Рейтинг: 0 / 0
18.10.2013, 23:18:09
    #38433594
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
kdvagoda Но на что намекает Buffers = 75 я там не нашел. Можете ткнуть носом?
раздел "Память", про кэш Классика. Рекомендую статьи, если они непонятны, вообще, любые, перечитывать по нескольку раз. Ничего стыдного в этом нет, я сам регулярно так делаю в отношении чужих (и своих) статей.
Кроме того, в этом разделе форума туча топиков на тему "классик кэш".

p.s. свою статью поправлю на эту тему.Спасибо, я не догнал, что Buffers говорит о количестве страниц кеша
...
Рейтинг: 0 / 0
18.10.2013, 23:19:17
    #38433596
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
agodaПросто я тестю на домашней машине отдельные запросы, база нерабочая.
на домашней машине ФБ как сервису делать нечего. его надо запускать вручную, с опцией -a, и проще всего как суперсервер.
http://www.ibase.ru/devinfo/inst_manual.htm

потратьте 10 минут, чтобы понять, как это устроено, и чтобы вы могли переключаться за 5 сек. между разными версиями или конфигурациями ФБ.
...
Рейтинг: 0 / 0
18.10.2013, 23:23:33
    #38433600
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
agodaСпасибо, я не догнал, что Buffers говорит о количестве страниц кеша
в gstat -h оно еще и page buffers называется. Трясця тому, кто все это по разному назвал. Впрочем, в отношении IBExpert все проще, можно попросить Хвастунова назвать этот параметр более правильно.
В отношении gstat -h поменять это можно разве что по feature request для FB 3.0.
...
Рейтинг: 0 / 0
18.10.2013, 23:26:37
    #38433602
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
kdvпотратьте 10 минут, чтобы понять, как это устроено
Кстати, у тебя там написано, что два IB разных версий можно запустить одновременно, но это
увы не так: один из них не найдёт свои лицензии и запускаться откажется.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
18.10.2013, 23:27:01
    #38433603
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
kdvagoda,
статью обновил. Стало понятнее? Если нет, прошу комментарии, буду редактировать до тех пор, пока не будет понятно даже начинающим.У меня, собственно, не статья вызвала непонимание, а значение вывода STAT ISQL. Не возникло ассоциаций со страницами кеша. Но про «по умолчанию» это хорошее замечание.
...
Рейтинг: 0 / 0
18.10.2013, 23:37:38
    #38433611
agoda
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
kdvagodaПросто я тестю на домашней машине отдельные запросы, база нерабочая.
на домашней машине ФБ как сервису делать нечего. его надо запускать вручную, с опцией -a, и проще всего как суперсервер.
http://www.ibase.ru/devinfo/inst_manual.htm

потратьте 10 минут, чтобы понять, как это устроено, и чтобы вы могли переключаться за 5 сек. между разными версиями или конфигурациями ФБ.Спасибо, прочел. Пока у меня нет большого количества конфигураций. А сервис висит и есть не просит.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите с запросом / 25 сообщений из 35, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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