2 dmitr, hvlad по поводу IN ()

Gold
Дата: 10.10.2005 16:00:14
Привет!
Поскольку эпсилоновская конференция поломалась, то напишу сюда:

1) Дима мне подтвердил что в списке IN может быть 1500 значений. На самом деле это не так. Проглатывает 1499 значений. При 1500 говорит Implementation limit exceeded. too many values (more than 1500) in member list to match against. У меня же никак не more than 1500, а именно 1500 в тестовом запросе было.

2) Я тут сравнивал запросы с кучей OR и списком IN - список IN однозначно быстрее компиллируется
- для списка IN: Prepare time = 125ms
- для кучи OR: Prepare time = 203ms

Собственно, нельзя ли в FB2 убрать это ограничение на 1500 значений в списке, вернее на 1499, потому что OR явно проигрывает?
Sash*
Дата: 10.10.2005 16:18:05
может лучше exests?
Лентяй
Дата: 10.10.2005 16:56:21
Gold
Привет!
Поскольку эпсилоновская конференция поломалась, то напишу сюда:

1) Дима мне подтвердил что в списке IN может быть 1500 значений. На самом деле это не так. Проглатывает 1499 значений. При 1500 говорит Implementation limit exceeded. too many values (more than 1500) in member list to match against. У меня же никак не more than 1500, а именно 1500 в тестовом запросе было.

2) Я тут сравнивал запросы с кучей OR и списком IN - список IN однозначно быстрее компиллируется
- для списка IN: Prepare time = 125ms
- для кучи OR: Prepare time = 203ms

Собственно, нельзя ли в FB2 убрать это ограничение на 1500 значений в списке, вернее на 1499, потому что OR явно проигрывает?

А откуда такое море значений в in ()? Может как-то по другому можно? А если нет - попробуй Union использовать...
Amris Mirddin
Дата: 10.10.2005 16:57:17
Gold

Собственно, нельзя ли в FB2 убрать это ограничение на 1500 значений в списке, вернее на 1499, потому что OR явно проигрывает?


Ты искренне веришь, что ограничение введено чиста из вредности? И разогнаться быстрее скорости света - тоже, по Его вредности? А насчёт проигрывает - я те вот что скажу.

1. В 90% случаев IN-ы больше чем из 10 значений образуются потому, что разработчик недодумал - а почему пользователя интересуют те или иные значения, и недоснабдил модель атрибутами и/или задачу диапазонными фильтрами на эти атрибуты.
2. В случае длинных списков натурал выигрывает у индексов, а случае натурала трюк where :param containing '~'||ID||'~' выигрывает у IN.
Gold
Дата: 10.10.2005 17:06:55
2 Amris Mirddin:

Да, а вариант с CONTAINING - это мысль! Спасибо! :-)
dimitr
Дата: 11.10.2005 12:04:43
IN выигрывает у OR только в текстовом парсинге. BLR в обоих случаях генерится и оптимизируется одинаково - создается OR-дерево. Ограничение воткнуто, чтобы ограничить полет фантазии некоторых извращенцев. К слову, на достаточно большом OR-списке (каким бы способом он не был задан) сервер наверняка выдаст stack overflow. Так что рекомендую искать другие методы решения.
Gold
Дата: 11.10.2005 12:13:40
Понимаете, у меня поисковая машина выдаёт кучу ID документов. Сколько их будет - никто не знает :-( А комбинация нескольких CONTAINING соединённых через OR - это нормально будет работать? Допустим в каждой строке в CONTAINING по 2 тыщи ID сцеплено и таких CONTAINING штуки 4.
Kull Damned
Дата: 11.10.2005 12:19:34
А нельзя эти ID в какую-нть псевдовременную таблу вылить и с ней JOIN сделать? Или это будет намного медленней?

Posted via ActualForum NNTP Server 1.3

Gold
Дата: 11.10.2005 12:31:35
Я бы сказал что не то чтобы немного медленнее, а в разы хотя бы потому что я 5000 ID разом запихнуть не смогу.
sag494
Дата: 11.10.2005 14:13:54
Привет,
Gold
Я бы сказал что не то чтобы немного медленнее, а в разы хотя бы
потому что я 5000 ID разом запихнуть не смогу.
поставил такой эксперимент
select max(t.id /*пк*/) from table t 
where :p_in containing '~'||t_.id||'~'
где в :p_in фигурирует 1000 значений. Время выполнения ~1.9сек.
Создал "псевдовременную" табличку tt из одного поля id (пк). Попытаюсь заполнять эту таблицу не с клиента, а почти с сервера. Создал хп, у которой один входной параметр - varchar (много), в этой хп в цикле разбираю этот входной параметр на составляющие (integer) и записываю в таблицу tt. Запускаю эту хп на выполнение со значением входного параметра равного :p_in из предыдущего примера: ~0.2сек.
Далее делаю
select max(t.id /*пк*/) from table t, tt where t.id=tt.id
Время выполнения ~0.016 сек. Итого: ~1.9 секунд супротив ~0.22сек.